@backstage/plugin-scaffolder-backend 1.33.0 → 2.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +110 -0
- package/dist/ScaffolderPlugin.cjs.js +0 -3
- package/dist/ScaffolderPlugin.cjs.js.map +1 -1
- package/dist/alpha.cjs.js +5 -9
- package/dist/alpha.cjs.js.map +1 -1
- package/dist/alpha.d.ts +1 -5
- package/dist/index.cjs.js +0 -26
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +45 -355
- package/dist/lib/templating/SecureTemplater.cjs.js.map +1 -1
- package/dist/scaffolder/actions/TemplateActionRegistry.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/template.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/templateActionHandler.cjs.js +4 -19
- package/dist/scaffolder/actions/builtin/fetch/templateActionHandler.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/StorageTaskBroker.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/TaskWorker.cjs.js.map +1 -1
- package/dist/service/{conditionExports.cjs.js → alpha.cjs.js} +1 -1
- package/dist/service/alpha.cjs.js.map +1 -0
- package/dist/service/permissions.cjs.js +14 -0
- package/dist/service/permissions.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +30 -95
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +33 -35
- package/dist/deprecated.cjs.js +0 -15
- package/dist/deprecated.cjs.js.map +0 -1
- package/dist/scaffolder/actions/deprecated.cjs.js +0 -48
- package/dist/scaffolder/actions/deprecated.cjs.js.map +0 -1
- package/dist/service/conditionExports.cjs.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.cjs.js","sources":["../../src/service/permissions.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PermissionRule } from '@backstage/plugin-permission-node';\nimport {\n TemplateEntityStepV1beta3,\n TemplateParametersV1beta3,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport { PermissionRuleParams } from '@backstage/plugin-permission-common';\n\n/**\n * @public\n */\nexport type TemplatePermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n TParams\n>;\nexport function isTemplatePermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is TemplatePermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_TEMPLATE;\n}\n\n/**\n *\n * @public\n */\nexport type ActionPermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_ACTION,\n TParams\n>;\nexport function isActionPermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is ActionPermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_ACTION;\n}\n"],"names":["RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","RESOURCE_TYPE_SCAFFOLDER_ACTION"],"mappings":";;;;AAsCO,SAAS,8BACd,cAC+C,EAAA;AAC/C,EAAA,OAAO,eAAe,YAAiB,KAAAA,uCAAA;AACzC;AAcO,SAAS,4BACd,cAC6C,EAAA;AAC7C,EAAA,OAAO,eAAe,YAAiB,KAAAC,qCAAA;AACzC;;;;;"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var backendCommon = require('@backstage/backend-common');
|
|
4
3
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
5
4
|
var catalogModel = require('@backstage/catalog-model');
|
|
6
5
|
var config = require('@backstage/config');
|
|
@@ -39,13 +38,6 @@ require('../scaffolder/actions/builtin/fetch/templateFile.examples.cjs.js');
|
|
|
39
38
|
require('../scaffolder/actions/builtin/filesystem/delete.examples.cjs.js');
|
|
40
39
|
require('../scaffolder/actions/builtin/filesystem/rename.examples.cjs.js');
|
|
41
40
|
require('../scaffolder/actions/builtin/filesystem/read.cjs.js');
|
|
42
|
-
require('@backstage/plugin-scaffolder-backend-module-github');
|
|
43
|
-
require('@backstage/plugin-scaffolder-backend-module-gitlab');
|
|
44
|
-
require('@backstage/plugin-scaffolder-backend-module-azure');
|
|
45
|
-
require('@backstage/plugin-scaffolder-backend-module-bitbucket');
|
|
46
|
-
require('@backstage/plugin-scaffolder-backend-module-bitbucket-cloud');
|
|
47
|
-
require('@backstage/plugin-scaffolder-backend-module-bitbucket-server');
|
|
48
|
-
require('@backstage/plugin-scaffolder-backend-module-gerrit');
|
|
49
41
|
var TemplateActionRegistry = require('../scaffolder/actions/TemplateActionRegistry.cjs.js');
|
|
50
42
|
var DatabaseTaskStore = require('../scaffolder/tasks/DatabaseTaskStore.cjs.js');
|
|
51
43
|
var StorageTaskBroker = require('../scaffolder/tasks/StorageTaskBroker.cjs.js');
|
|
@@ -54,65 +46,16 @@ var createDryRunner = require('../scaffolder/dryrun/createDryRunner.cjs.js');
|
|
|
54
46
|
var checkPermissions = require('../util/checkPermissions.cjs.js');
|
|
55
47
|
var helpers = require('./helpers.cjs.js');
|
|
56
48
|
var rules = require('./rules.cjs.js');
|
|
57
|
-
var
|
|
49
|
+
var permissions = require('./permissions.cjs.js');
|
|
58
50
|
|
|
59
51
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
60
52
|
|
|
61
53
|
var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
62
54
|
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
63
55
|
|
|
64
|
-
function isTemplatePermissionRuleInput(permissionRule) {
|
|
65
|
-
return permissionRule.resourceType === alpha.RESOURCE_TYPE_SCAFFOLDER_TEMPLATE;
|
|
66
|
-
}
|
|
67
|
-
function isActionPermissionRuleInput(permissionRule) {
|
|
68
|
-
return permissionRule.resourceType === alpha.RESOURCE_TYPE_SCAFFOLDER_ACTION;
|
|
69
|
-
}
|
|
70
56
|
function isSupportedTemplate(entity) {
|
|
71
57
|
return entity.apiVersion === "scaffolder.backstage.io/v1beta3";
|
|
72
58
|
}
|
|
73
|
-
function buildDefaultIdentityClient(options) {
|
|
74
|
-
return {
|
|
75
|
-
getIdentity: async ({ request }) => {
|
|
76
|
-
const header = request.headers.authorization;
|
|
77
|
-
const { logger } = options;
|
|
78
|
-
if (!header) {
|
|
79
|
-
return void 0;
|
|
80
|
-
}
|
|
81
|
-
try {
|
|
82
|
-
const token = header.match(/^Bearer\s(\S+\.\S+\.\S+)$/i)?.[1];
|
|
83
|
-
if (!token) {
|
|
84
|
-
throw new TypeError("Expected Bearer with JWT");
|
|
85
|
-
}
|
|
86
|
-
const [_header, rawPayload, _signature] = token.split(".");
|
|
87
|
-
const payload = JSON.parse(
|
|
88
|
-
Buffer.from(rawPayload, "base64").toString()
|
|
89
|
-
);
|
|
90
|
-
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
|
|
91
|
-
throw new TypeError("Malformed JWT payload");
|
|
92
|
-
}
|
|
93
|
-
const sub = payload.sub;
|
|
94
|
-
if (typeof sub !== "string") {
|
|
95
|
-
throw new TypeError("Expected string sub claim");
|
|
96
|
-
}
|
|
97
|
-
if (sub === "backstage-server") {
|
|
98
|
-
return void 0;
|
|
99
|
-
}
|
|
100
|
-
catalogModel.parseEntityRef(sub);
|
|
101
|
-
return {
|
|
102
|
-
identity: {
|
|
103
|
-
userEntityRef: sub,
|
|
104
|
-
ownershipEntityRefs: [],
|
|
105
|
-
type: "user"
|
|
106
|
-
},
|
|
107
|
-
token
|
|
108
|
-
};
|
|
109
|
-
} catch (e) {
|
|
110
|
-
logger.error(`Invalid authorization header: ${errors.stringifyError(e)}`);
|
|
111
|
-
return void 0;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
59
|
const readDuration = (config$1, key, defaultValue) => {
|
|
117
60
|
if (config$1.has(key)) {
|
|
118
61
|
return config.readDurationFromConfig(config$1, { key });
|
|
@@ -129,24 +72,18 @@ async function createRouter(options) {
|
|
|
129
72
|
database,
|
|
130
73
|
catalogClient,
|
|
131
74
|
actions,
|
|
132
|
-
taskWorkers,
|
|
133
75
|
scheduler,
|
|
134
76
|
additionalTemplateFilters,
|
|
135
77
|
additionalTemplateGlobals,
|
|
136
78
|
additionalWorkspaceProviders,
|
|
137
|
-
permissions,
|
|
79
|
+
permissions: permissions$1,
|
|
138
80
|
permissionRules,
|
|
139
|
-
discovery: discovery$1 = discovery.HostDiscovery.fromConfig(config),
|
|
140
|
-
identity = buildDefaultIdentityClient(options),
|
|
141
81
|
autocompleteHandlers = {},
|
|
142
82
|
events: eventsService,
|
|
83
|
+
auth,
|
|
84
|
+
httpAuth,
|
|
143
85
|
auditor
|
|
144
86
|
} = options;
|
|
145
|
-
const { auth, httpAuth } = backendCommon.createLegacyAuthAdapters({
|
|
146
|
-
...options,
|
|
147
|
-
identity,
|
|
148
|
-
discovery: discovery$1
|
|
149
|
-
});
|
|
150
87
|
const concurrentTasksLimit = options.concurrentTasksLimit ?? options.config.getOptionalNumber("scaffolder.concurrentTasksLimit");
|
|
151
88
|
const logger = parentLogger.child({ plugin: "scaffolder" });
|
|
152
89
|
const workingDirectory = await helpers.getWorkingDirectory(config, logger);
|
|
@@ -208,21 +145,19 @@ async function createRouter(options) {
|
|
|
208
145
|
const gracefulShutdown = config.getOptionalBoolean(
|
|
209
146
|
"scaffolder.EXPERIMENTAL_gracefulShutdown"
|
|
210
147
|
);
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
workers.push(worker);
|
|
225
|
-
}
|
|
148
|
+
const worker = await TaskWorker.TaskWorker.create({
|
|
149
|
+
taskBroker,
|
|
150
|
+
actionRegistry,
|
|
151
|
+
integrations,
|
|
152
|
+
logger,
|
|
153
|
+
auditor,
|
|
154
|
+
workingDirectory,
|
|
155
|
+
concurrentTasksLimit,
|
|
156
|
+
permissions: permissions$1,
|
|
157
|
+
gracefulShutdown,
|
|
158
|
+
...templateExtensions
|
|
159
|
+
});
|
|
160
|
+
workers.push(worker);
|
|
226
161
|
}
|
|
227
162
|
const actionsToRegister = Array.isArray(actions) ? actions : createBuiltinActions.createBuiltinActions({
|
|
228
163
|
integrations,
|
|
@@ -249,7 +184,7 @@ async function createRouter(options) {
|
|
|
249
184
|
logger,
|
|
250
185
|
auditor,
|
|
251
186
|
workingDirectory,
|
|
252
|
-
permissions,
|
|
187
|
+
permissions: permissions$1,
|
|
253
188
|
...templateExtensions
|
|
254
189
|
});
|
|
255
190
|
const templateRules = Object.values(
|
|
@@ -260,9 +195,9 @@ async function createRouter(options) {
|
|
|
260
195
|
);
|
|
261
196
|
if (permissionRules) {
|
|
262
197
|
templateRules.push(
|
|
263
|
-
...permissionRules.filter(isTemplatePermissionRuleInput)
|
|
198
|
+
...permissionRules.filter(permissions.isTemplatePermissionRuleInput)
|
|
264
199
|
);
|
|
265
|
-
actionRules.push(...permissionRules.filter(isActionPermissionRuleInput));
|
|
200
|
+
actionRules.push(...permissionRules.filter(permissions.isActionPermissionRuleInput));
|
|
266
201
|
}
|
|
267
202
|
const isAuthorized = pluginPermissionNode.createConditionAuthorizer(Object.values(templateRules));
|
|
268
203
|
const permissionIntegrationRouter = pluginPermissionNode.createPermissionIntegrationRouter({
|
|
@@ -361,7 +296,7 @@ async function createRouter(options) {
|
|
|
361
296
|
await checkPermissions.checkPermission({
|
|
362
297
|
credentials,
|
|
363
298
|
permissions: [alpha.taskCreatePermission],
|
|
364
|
-
permissionService: permissions
|
|
299
|
+
permissionService: permissions$1
|
|
365
300
|
});
|
|
366
301
|
const { token } = await auth.getPluginRequestToken({
|
|
367
302
|
onBehalfOf: credentials,
|
|
@@ -450,7 +385,7 @@ async function createRouter(options) {
|
|
|
450
385
|
await checkPermissions.checkPermission({
|
|
451
386
|
credentials,
|
|
452
387
|
permissions: [alpha.taskReadPermission],
|
|
453
|
-
permissionService: permissions
|
|
388
|
+
permissionService: permissions$1
|
|
454
389
|
});
|
|
455
390
|
if (!taskBroker.list) {
|
|
456
391
|
throw new Error(
|
|
@@ -505,7 +440,7 @@ async function createRouter(options) {
|
|
|
505
440
|
await checkPermissions.checkPermission({
|
|
506
441
|
credentials,
|
|
507
442
|
permissions: [alpha.taskReadPermission],
|
|
508
|
-
permissionService: permissions
|
|
443
|
+
permissionService: permissions$1
|
|
509
444
|
});
|
|
510
445
|
const task = await taskBroker.get(taskId);
|
|
511
446
|
if (!task) {
|
|
@@ -534,7 +469,7 @@ async function createRouter(options) {
|
|
|
534
469
|
await checkPermissions.checkPermission({
|
|
535
470
|
credentials,
|
|
536
471
|
permissions: [alpha.taskCancelPermission, alpha.taskReadPermission],
|
|
537
|
-
permissionService: permissions
|
|
472
|
+
permissionService: permissions$1
|
|
538
473
|
});
|
|
539
474
|
await taskBroker.cancel?.(taskId);
|
|
540
475
|
await auditorEvent?.success();
|
|
@@ -559,7 +494,7 @@ async function createRouter(options) {
|
|
|
559
494
|
await checkPermissions.checkPermission({
|
|
560
495
|
credentials,
|
|
561
496
|
permissions: [alpha.taskCreatePermission, alpha.taskReadPermission],
|
|
562
|
-
permissionService: permissions
|
|
497
|
+
permissionService: permissions$1
|
|
563
498
|
});
|
|
564
499
|
await auditorEvent?.success();
|
|
565
500
|
const { token } = await auth.getPluginRequestToken({
|
|
@@ -596,7 +531,7 @@ async function createRouter(options) {
|
|
|
596
531
|
await checkPermissions.checkPermission({
|
|
597
532
|
credentials,
|
|
598
533
|
permissions: [alpha.taskReadPermission],
|
|
599
|
-
permissionService: permissions
|
|
534
|
+
permissionService: permissions$1
|
|
600
535
|
});
|
|
601
536
|
const after = req.query.after !== void 0 ? Number(req.query.after) : void 0;
|
|
602
537
|
logger.debug(`Event stream observing taskId '${taskId}' opened`);
|
|
@@ -657,7 +592,7 @@ data: ${JSON.stringify(event)}
|
|
|
657
592
|
await checkPermissions.checkPermission({
|
|
658
593
|
credentials,
|
|
659
594
|
permissions: [alpha.taskReadPermission],
|
|
660
|
-
permissionService: permissions
|
|
595
|
+
permissionService: permissions$1
|
|
661
596
|
});
|
|
662
597
|
const after = Number(req.query.after) || void 0;
|
|
663
598
|
const timeout = setTimeout(() => {
|
|
@@ -698,7 +633,7 @@ data: ${JSON.stringify(event)}
|
|
|
698
633
|
await checkPermissions.checkPermission({
|
|
699
634
|
credentials,
|
|
700
635
|
permissions: [alpha.taskCreatePermission],
|
|
701
|
-
permissionService: permissions
|
|
636
|
+
permissionService: permissions$1
|
|
702
637
|
});
|
|
703
638
|
const bodySchema = z.z.object({
|
|
704
639
|
template: z.z.unknown(),
|
|
@@ -839,10 +774,10 @@ data: ${JSON.stringify(event)}
|
|
|
839
774
|
`Unsupported apiVersion field in schema entity, ${template.apiVersion}`
|
|
840
775
|
);
|
|
841
776
|
}
|
|
842
|
-
if (!permissions) {
|
|
777
|
+
if (!permissions$1) {
|
|
843
778
|
return template;
|
|
844
779
|
}
|
|
845
|
-
const [parameterDecision, stepDecision] = await permissions.authorizeConditional(
|
|
780
|
+
const [parameterDecision, stepDecision] = await permissions$1.authorizeConditional(
|
|
846
781
|
[
|
|
847
782
|
{ permission: alpha.templateParameterReadPermission },
|
|
848
783
|
{ permission: alpha.templateStepReadPermission }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createLegacyAuthAdapters } from '@backstage/backend-common';\nimport {\n AuditorService,\n AuthService,\n BackstageCredentials,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LifecycleService,\n PermissionsService,\n resolveSafeChildPath,\n SchedulerService,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { Config, readDurationFromConfig } from '@backstage/config';\nimport { InputError, NotFoundError, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n IdentityApi,\n IdentityApiGetIdentityRequest,\n} from '@backstage/plugin-auth-node';\nimport { EventsService } from '@backstage/plugin-events-node';\nimport { PermissionRuleParams } from '@backstage/plugin-permission-common';\nimport {\n createConditionAuthorizer,\n createPermissionIntegrationRouter,\n PermissionRule,\n} from '@backstage/plugin-permission-node';\nimport {\n TaskSpec,\n TemplateEntityStepV1beta3,\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n TemplateParametersV1beta3,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n scaffolderActionPermissions,\n scaffolderPermissions,\n scaffolderTemplatePermissions,\n taskCancelPermission,\n taskCreatePermission,\n taskReadPermission,\n templateParameterReadPermission,\n templateStepReadPermission,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskBroker,\n TaskStatus,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n CreatedTemplateFilter,\n CreatedTemplateGlobal,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { HumanDuration, JsonObject, JsonValue } from '@backstage/types';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { validate } from 'jsonschema';\nimport { Duration } from 'luxon';\nimport { pathToFileURL } from 'url';\nimport { v4 as uuid } from 'uuid';\nimport { Logger } from 'winston';\nimport { z } from 'zod';\nimport {\n createBuiltinActions,\n DatabaseTaskStore,\n TaskWorker,\n TemplateActionRegistry,\n} from '../scaffolder';\nimport { createDryRunner } from '../scaffolder/dryrun';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport { InternalTaskSecrets } from '../scaffolder/tasks/types';\nimport { checkPermission } from '../util/checkPermissions';\nimport {\n findTemplate,\n getEntityBaseUrl,\n getWorkingDirectory,\n parseNumberParam,\n parseStringsParam,\n} from './helpers';\nimport { scaffolderActionRules, scaffolderTemplateRules } from './rules';\nimport { HostDiscovery } from '@backstage/backend-defaults/discovery';\nimport {\n convertFiltersToRecord,\n convertGlobalsToRecord,\n extractFilterMetadata,\n extractGlobalFunctionMetadata,\n extractGlobalValueMetadata,\n} from '../util/templating';\nimport { createDefaultFilters } from '../lib/templating/filters/createDefaultFilters';\n\n/**\n *\n * @public\n */\nexport type TemplatePermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n TParams\n>;\nfunction isTemplatePermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is TemplatePermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_TEMPLATE;\n}\n\n/**\n *\n * @public\n */\nexport type ActionPermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_ACTION,\n TParams\n>;\nfunction isActionPermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is ActionPermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_ACTION;\n}\n\n/**\n * RouterOptions\n *\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n reader: UrlReaderService;\n lifecycle?: LifecycleService;\n database: DatabaseService;\n catalogClient: CatalogApi;\n scheduler?: SchedulerService;\n actions?: TemplateAction<any, any, any>[];\n /**\n * @deprecated taskWorkers is deprecated in favor of concurrentTasksLimit option with a single TaskWorker\n * @defaultValue 1\n */\n taskWorkers?: number;\n /**\n * Sets the number of concurrent tasks that can be run at any given time on the TaskWorker\n * @defaultValue 10\n */\n concurrentTasksLimit?: number;\n taskBroker?: TaskBroker;\n additionalTemplateFilters?:\n | Record<string, TemplateFilter>\n | CreatedTemplateFilter<any, any>[];\n additionalTemplateGlobals?:\n | Record<string, TemplateGlobal>\n | CreatedTemplateGlobal[];\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>;\n permissions?: PermissionsService;\n permissionRules?: Array<\n TemplatePermissionRuleInput | ActionPermissionRuleInput\n >;\n auth?: AuthService;\n httpAuth?: HttpAuthService;\n identity?: IdentityApi;\n discovery?: DiscoveryService;\n events?: EventsService;\n auditor?: AuditorService;\n autocompleteHandlers?: Record<string, AutocompleteHandler>;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\n/*\n * @deprecated This function remains as the DefaultIdentityClient behaves slightly differently to the pre-existing\n * scaffolder behaviour. Specifically if the token fails to parse, the DefaultIdentityClient will raise an error.\n * The scaffolder did not raise an error in this case. As such we chose to allow it to behave as it did previously\n * until someone explicitly passes an IdentityApi. When we have reasonable confidence that most backstage deployments\n * are using the IdentityApi, we can remove this function.\n */\nfunction buildDefaultIdentityClient(options: RouterOptions): IdentityApi {\n return {\n getIdentity: async ({ request }: IdentityApiGetIdentityRequest) => {\n const header = request.headers.authorization;\n const { logger } = options;\n\n if (!header) {\n return undefined;\n }\n\n try {\n const token = header.match(/^Bearer\\s(\\S+\\.\\S+\\.\\S+)$/i)?.[1];\n if (!token) {\n throw new TypeError('Expected Bearer with JWT');\n }\n\n const [_header, rawPayload, _signature] = token.split('.');\n const payload: JsonValue = JSON.parse(\n Buffer.from(rawPayload, 'base64').toString(),\n );\n\n if (\n typeof payload !== 'object' ||\n payload === null ||\n Array.isArray(payload)\n ) {\n throw new TypeError('Malformed JWT payload');\n }\n\n const sub = payload.sub;\n if (typeof sub !== 'string') {\n throw new TypeError('Expected string sub claim');\n }\n\n if (sub === 'backstage-server') {\n return undefined;\n }\n\n // Check that it's a valid ref, otherwise this will throw.\n parseEntityRef(sub);\n\n return {\n identity: {\n userEntityRef: sub,\n ownershipEntityRefs: [],\n type: 'user',\n },\n token,\n };\n } catch (e) {\n logger.error(`Invalid authorization header: ${stringifyError(e)}`);\n return undefined;\n }\n },\n };\n}\n\nconst readDuration = (\n config: Config,\n key: string,\n defaultValue: HumanDuration,\n) => {\n if (config.has(key)) {\n return readDurationFromConfig(config, { key });\n }\n return defaultValue;\n};\n\n/**\n * A method to create a router for the scaffolder backend plugin.\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n // Be generous in upload size to support a wide range of templates in dry-run mode.\n router.use(express.json({ limit: '10MB' }));\n\n const {\n logger: parentLogger,\n config,\n reader,\n database,\n catalogClient,\n actions,\n taskWorkers,\n scheduler,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n additionalWorkspaceProviders,\n permissions,\n permissionRules,\n discovery = HostDiscovery.fromConfig(config),\n identity = buildDefaultIdentityClient(options),\n autocompleteHandlers = {},\n events: eventsService,\n auditor,\n } = options;\n\n const { auth, httpAuth } = createLegacyAuthAdapters({\n ...options,\n identity,\n discovery,\n });\n\n const concurrentTasksLimit =\n options.concurrentTasksLimit ??\n options.config.getOptionalNumber('scaffolder.concurrentTasksLimit');\n\n const logger = parentLogger.child({ plugin: 'scaffolder' });\n\n const workingDirectory = await getWorkingDirectory(config, logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n let taskBroker: TaskBroker;\n if (!options.taskBroker) {\n const databaseTaskStore = await DatabaseTaskStore.create({\n database,\n events: eventsService,\n });\n taskBroker = new StorageTaskBroker(\n databaseTaskStore,\n logger,\n config,\n auth,\n additionalWorkspaceProviders,\n auditor,\n );\n\n if (scheduler && databaseTaskStore.listStaleTasks) {\n await scheduler.scheduleTask({\n id: 'close_stale_tasks',\n frequency: readDuration(\n config,\n 'scaffolder.taskTimeoutJanitorFrequency',\n {\n minutes: 5,\n },\n ),\n timeout: { minutes: 15 },\n fn: async () => {\n const { tasks } = await databaseTaskStore.listStaleTasks({\n timeoutS: Duration.fromObject(\n readDuration(config, 'scaffolder.taskTimeout', {\n hours: 24,\n }),\n ).as('seconds'),\n });\n\n for (const task of tasks) {\n await databaseTaskStore.shutdownTask(task);\n logger.info(`Successfully closed stale task ${task.taskId}`);\n }\n },\n });\n }\n } else {\n taskBroker = options.taskBroker;\n }\n\n const actionRegistry = new TemplateActionRegistry();\n\n const templateExtensions = {\n additionalTemplateFilters: convertFiltersToRecord(\n additionalTemplateFilters,\n ),\n additionalTemplateGlobals: convertGlobalsToRecord(\n additionalTemplateGlobals,\n ),\n };\n\n const workers: TaskWorker[] = [];\n if (concurrentTasksLimit !== 0) {\n const gracefulShutdown = config.getOptionalBoolean(\n 'scaffolder.EXPERIMENTAL_gracefulShutdown',\n );\n\n for (let i = 0; i < (taskWorkers || 1); i++) {\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n concurrentTasksLimit,\n permissions,\n gracefulShutdown,\n ...templateExtensions,\n });\n workers.push(worker);\n }\n }\n\n const actionsToRegister = Array.isArray(actions)\n ? actions\n : createBuiltinActions({\n integrations,\n catalogClient,\n reader,\n config,\n auth,\n ...templateExtensions,\n });\n\n actionsToRegister.forEach(action => actionRegistry.register(action));\n\n const launchWorkers = () => workers.forEach(worker => worker.start());\n\n const shutdownWorkers = async () => {\n await Promise.allSettled(workers.map(worker => worker.stop()));\n };\n\n if (options.lifecycle) {\n options.lifecycle.addStartupHook(launchWorkers);\n options.lifecycle.addShutdownHook(shutdownWorkers);\n } else {\n launchWorkers();\n }\n\n const dryRunner = createDryRunner({\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n permissions,\n ...templateExtensions,\n });\n\n const templateRules: TemplatePermissionRuleInput[] = Object.values(\n scaffolderTemplateRules,\n );\n const actionRules: ActionPermissionRuleInput[] = Object.values(\n scaffolderActionRules,\n );\n\n if (permissionRules) {\n templateRules.push(\n ...permissionRules.filter(isTemplatePermissionRuleInput),\n );\n actionRules.push(...permissionRules.filter(isActionPermissionRuleInput));\n }\n\n const isAuthorized = createConditionAuthorizer(Object.values(templateRules));\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n resources: [\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n permissions: scaffolderTemplatePermissions,\n rules: templateRules,\n },\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n permissions: scaffolderActionPermissions,\n rules: actionRules,\n },\n ],\n permissions: scaffolderPermissions,\n });\n\n router.use(permissionIntegrationRouter);\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const requestedTemplateRef = `${req.params.kind}:${req.params.namespace}/${req.params.name}`;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'template-parameter-schema',\n request: req,\n meta: { templateRef: requestedTemplateRef },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const template = await authorizeTemplate(\n req.params,\n token,\n credentials,\n );\n\n const parameters = [template.spec.parameters ?? []].flat();\n\n const presentation = template.spec.presentation;\n\n const templateRef = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n await auditorEvent?.success({ meta: { templateRef: templateRef } });\n\n res.json({\n title: template.metadata.title ?? template.metadata.name,\n ...(presentation ? { presentation } : {}),\n description: template.metadata.description,\n 'ui:options': template.metadata['ui:options'],\n steps: parameters.map(schema => ({\n title: schema.title ?? 'Please enter the following information',\n description: schema.description,\n schema,\n })),\n EXPERIMENTAL_formDecorators:\n template.spec.EXPERIMENTAL_formDecorators,\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n },\n )\n .get('/v2/actions', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'action-fetch',\n request: req,\n });\n\n try {\n const actionsList = actionRegistry.list().map(action => {\n return {\n id: action.id,\n description: action.description,\n examples: action.examples,\n schema: action.schema,\n };\n });\n\n await auditorEvent?.success();\n\n res.json(actionsList);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks', async (req, res) => {\n const templateRef: string = req.body.templateRef;\n const { kind, namespace, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'create',\n templateRef: templateRef,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\n : undefined;\n\n let auditLog = `Scaffolding task for ${templateRef}`;\n if (userEntityRef) {\n auditLog += ` created by ${userEntityRef}`;\n }\n logger.info(auditLog);\n\n const values = req.body.values;\n\n const template = await authorizeTemplate(\n { kind, namespace, name },\n token,\n credentials,\n );\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(values, parameters);\n\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not create entity',\n ),\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const baseUrl = getEntityBaseUrl(template);\n\n const taskSpec: TaskSpec = {\n apiVersion: template.apiVersion,\n steps: template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n })),\n EXPERIMENTAL_recovery: template.spec.EXPERIMENTAL_recovery,\n output: template.spec.output ?? {},\n parameters: values,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n templateInfo: {\n entityRef: stringifyEntityRef({ kind, name, namespace }),\n baseUrl,\n entity: {\n metadata: template.metadata,\n },\n },\n };\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n const result = await taskBroker.dispatch({\n spec: taskSpec,\n createdBy: userEntityRef,\n secrets,\n });\n\n await auditorEvent?.success({ meta: { taskId: result.taskId } });\n\n res.status(201).json({ id: result.taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'list',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n if (!taskBroker.list) {\n throw new Error(\n 'TaskBroker does not support listing tasks, please implement the list method on the TaskBroker.',\n );\n }\n\n const createdBy = parseStringsParam(req.query.createdBy, 'createdBy');\n const status = parseStringsParam(req.query.status, 'status');\n\n const order = parseStringsParam(req.query.order, 'order')?.map(item => {\n const match = item.match(/^(asc|desc):(.+)$/);\n if (!match) {\n throw new InputError(\n `Invalid order parameter \"${item}\", expected \"<asc or desc>:<field name>\"`,\n );\n }\n\n return {\n order: match[1] as 'asc' | 'desc',\n field: match[2],\n };\n });\n\n const limit = parseNumberParam(req.query.limit, 'limit');\n const offset = parseNumberParam(req.query.offset, 'offset');\n\n const tasks = await taskBroker.list({\n filters: {\n createdBy,\n status: status ? (status as TaskStatus[]) : undefined,\n },\n order,\n pagination: {\n limit: limit ? limit[0] : undefined,\n offset: offset ? offset[0] : undefined,\n },\n });\n\n await auditorEvent?.success();\n\n res.status(200).json(tasks);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'get',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const task = await taskBroker.get(taskId);\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n\n await auditorEvent?.success();\n\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/cancel', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'cancel',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCancelPermission, taskReadPermission],\n permissionService: permissions,\n });\n\n await taskBroker.cancel?.(taskId);\n\n await auditorEvent?.success();\n\n res.status(200).json({ status: 'cancelled' });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/retry', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'retry',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission, taskReadPermission],\n permissionService: permissions,\n });\n\n await auditorEvent?.success();\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n await taskBroker.retry?.({ secrets, taskId });\n res.status(201).json({ id: taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId/eventstream', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'stream',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n logger.debug(`Event stream observing taskId '${taskId}' opened`);\n\n // Mandatory headers and http status to keep connection open\n res.writeHead(200, {\n Connection: 'keep-alive',\n 'Cache-Control': 'no-cache',\n 'Content-Type': 'text/event-stream',\n });\n\n // After client opens connection send all events as string\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n res.end();\n },\n next: ({ events }) => {\n let shouldUnsubscribe = false;\n for (const event of events) {\n res.write(\n `event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n if (event.type === 'completion' && !event.isTaskRecoverable) {\n shouldUnsubscribe = true;\n }\n }\n // res.flush() is only available with the compression middleware\n res.flush?.();\n if (shouldUnsubscribe) {\n subscription.unsubscribe();\n res.end();\n }\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', async () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n await auditorEvent?.success();\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'events',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const after = Number(req.query.after) || undefined;\n\n // cancel the request after 30 seconds. this aligns with the recommendations of RFC 6202.\n const timeout = setTimeout(() => {\n res.json([]);\n }, 30_000);\n\n // Get all known events after an id (always includes the completion event) and return the first callback\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n },\n next: async ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\n await auditorEvent?.success();\n res.json(events);\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n clearTimeout(timeout);\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/dry-run', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'dry-run',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const bodySchema = z.object({\n template: z.unknown(),\n values: z.record(z.unknown()),\n secrets: z.record(z.string()).optional(),\n directoryContents: z.array(\n z.object({ path: z.string(), base64Content: z.string() }),\n ),\n });\n const body = await bodySchema.parseAsync(req.body).catch(e => {\n throw new InputError(`Malformed request: ${e}`);\n });\n\n const template = body.template as TemplateEntityV1beta3;\n if (!(await templateEntityV1beta3Validator.check(template))) {\n throw new InputError('Input template is not a template');\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\n : undefined;\n\n const templateRef: string = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(body.values, parameters);\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not execute dry run',\n ),\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const steps = template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n }));\n\n const dryRunId = uuid();\n const contentsPath = resolveSafeChildPath(\n workingDirectory,\n `dry-run-content-${dryRunId}`,\n );\n const templateInfo = {\n entityRef: 'template:default/dry-run',\n entity: {\n metadata: template.metadata,\n },\n baseUrl: pathToFileURL(\n resolveSafeChildPath(contentsPath, 'template.yaml'),\n ).toString(),\n };\n\n const result = await dryRunner({\n spec: {\n apiVersion: template.apiVersion,\n steps,\n output: template.spec.output ?? {},\n parameters: body.values as JsonObject,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n },\n templateInfo: templateInfo,\n directoryContents: (body.directoryContents ?? []).map(file => ({\n path: file.path,\n content: Buffer.from(file.base64Content, 'base64'),\n })),\n secrets: {\n ...body.secrets,\n ...(token && { backstageToken: token }),\n },\n credentials,\n });\n\n await auditorEvent?.success({\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(200).json({\n ...result,\n steps,\n directoryContents: result.directoryContents.map(file => ({\n path: file.path,\n executable: file.executable,\n base64Content: file.content.toString('base64'),\n })),\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/autocomplete/:provider/:resource', async (req, res) => {\n const { token, context } = req.body;\n const { provider, resource } = req.params;\n\n if (!token) throw new InputError('Missing token query parameter');\n\n if (!autocompleteHandlers[provider]) {\n throw new InputError(`Unsupported provider: ${provider}`);\n }\n\n const { results } = await autocompleteHandlers[provider]({\n resource,\n token,\n context,\n });\n\n res.status(200).json({ results });\n })\n .get('/v2/templating-extensions', async (_req, res) => {\n res.status(200).json({\n filters: {\n ...extractFilterMetadata(createDefaultFilters({ integrations })),\n ...extractFilterMetadata(additionalTemplateFilters),\n },\n globals: {\n functions: extractGlobalFunctionMetadata(additionalTemplateGlobals),\n values: extractGlobalValueMetadata(additionalTemplateGlobals),\n },\n });\n });\n\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n async function authorizeTemplate(\n entityRef: CompoundEntityRef,\n token: string | undefined,\n credentials: BackstageCredentials,\n ) {\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef,\n token,\n });\n\n if (!isSupportedTemplate(template)) {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n\n if (!permissions) {\n return template;\n }\n\n const [parameterDecision, stepDecision] =\n await permissions.authorizeConditional(\n [\n { permission: templateParameterReadPermission },\n { permission: templateStepReadPermission },\n ],\n { credentials },\n );\n\n // Authorize parameters\n if (Array.isArray(template.spec.parameters)) {\n template.spec.parameters = template.spec.parameters.filter(step =>\n isAuthorized(parameterDecision, step),\n );\n } else if (\n template.spec.parameters &&\n !isAuthorized(parameterDecision, template.spec.parameters)\n ) {\n template.spec.parameters = undefined;\n }\n\n // Authorize steps\n template.spec.steps = template.spec.steps.filter(step =>\n isAuthorized(stepDecision, step),\n );\n\n return template;\n }\n\n return app;\n}\n"],"names":["RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","RESOURCE_TYPE_SCAFFOLDER_ACTION","parseEntityRef","stringifyError","config","readDurationFromConfig","Router","express","discovery","HostDiscovery","createLegacyAuthAdapters","getWorkingDirectory","ScmIntegrations","DatabaseTaskStore","StorageTaskBroker","Duration","TemplateActionRegistry","convertFiltersToRecord","convertGlobalsToRecord","TaskWorker","createBuiltinActions","createDryRunner","scaffolderTemplateRules","scaffolderActionRules","createConditionAuthorizer","createPermissionIntegrationRouter","scaffolderTemplatePermissions","scaffolderActionPermissions","scaffolderPermissions","checkPermission","taskCreatePermission","result","validate","getEntityBaseUrl","stringifyEntityRef","taskReadPermission","parseStringsParam","InputError","parseNumberParam","NotFoundError","taskCancelPermission","z","templateEntityV1beta3Validator","uuid","resolveSafeChildPath","pathToFileURL","extractFilterMetadata","createDefaultFilters","extractGlobalFunctionMetadata","extractGlobalValueMetadata","findTemplate","templateParameterReadPermission","templateStepReadPermission"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AuditorService,\n AuthService,\n BackstageCredentials,\n DatabaseService,\n HttpAuthService,\n LifecycleService,\n PermissionsService,\n resolveSafeChildPath,\n SchedulerService,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { Config, readDurationFromConfig } from '@backstage/config';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\n\nimport { EventsService } from '@backstage/plugin-events-node';\n\nimport {\n createConditionAuthorizer,\n createPermissionIntegrationRouter,\n} from '@backstage/plugin-permission-node';\nimport {\n TaskSpec,\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n scaffolderActionPermissions,\n scaffolderPermissions,\n scaffolderTemplatePermissions,\n taskCancelPermission,\n taskCreatePermission,\n taskReadPermission,\n templateParameterReadPermission,\n templateStepReadPermission,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskBroker,\n TaskStatus,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n CreatedTemplateFilter,\n CreatedTemplateGlobal,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { HumanDuration, JsonObject } from '@backstage/types';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { validate } from 'jsonschema';\nimport { Duration } from 'luxon';\nimport { pathToFileURL } from 'url';\nimport { v4 as uuid } from 'uuid';\nimport { Logger } from 'winston';\nimport { z } from 'zod';\nimport {\n createBuiltinActions,\n DatabaseTaskStore,\n TaskWorker,\n TemplateActionRegistry,\n} from '../scaffolder';\nimport { createDryRunner } from '../scaffolder/dryrun';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport { InternalTaskSecrets } from '../scaffolder/tasks/types';\nimport { checkPermission } from '../util/checkPermissions';\nimport {\n findTemplate,\n getEntityBaseUrl,\n getWorkingDirectory,\n parseNumberParam,\n parseStringsParam,\n} from './helpers';\nimport { scaffolderActionRules, scaffolderTemplateRules } from './rules';\nimport {\n convertFiltersToRecord,\n convertGlobalsToRecord,\n extractFilterMetadata,\n extractGlobalFunctionMetadata,\n extractGlobalValueMetadata,\n} from '../util/templating';\nimport { createDefaultFilters } from '../lib/templating/filters/createDefaultFilters';\nimport {\n ActionPermissionRuleInput,\n isActionPermissionRuleInput,\n isTemplatePermissionRuleInput,\n TemplatePermissionRuleInput,\n} from './permissions';\n\n/**\n * RouterOptions\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n reader: UrlReaderService;\n lifecycle?: LifecycleService;\n database: DatabaseService;\n catalogClient: CatalogApi;\n scheduler?: SchedulerService;\n actions?: TemplateAction<any, any, any>[];\n /**\n * Sets the number of concurrent tasks that can be run at any given time on the TaskWorker\n * @defaultValue 10\n */\n concurrentTasksLimit?: number;\n taskBroker?: TaskBroker;\n additionalTemplateFilters?:\n | Record<string, TemplateFilter>\n | CreatedTemplateFilter<any, any>[];\n additionalTemplateGlobals?:\n | Record<string, TemplateGlobal>\n | CreatedTemplateGlobal[];\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>;\n permissions?: PermissionsService;\n permissionRules?: Array<\n TemplatePermissionRuleInput | ActionPermissionRuleInput\n >;\n auth: AuthService;\n httpAuth: HttpAuthService;\n events?: EventsService;\n auditor?: AuditorService;\n autocompleteHandlers?: Record<string, AutocompleteHandler>;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\nconst readDuration = (\n config: Config,\n key: string,\n defaultValue: HumanDuration,\n) => {\n if (config.has(key)) {\n return readDurationFromConfig(config, { key });\n }\n return defaultValue;\n};\n\n/**\n * A method to create a router for the scaffolder backend plugin.\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n // Be generous in upload size to support a wide range of templates in dry-run mode.\n router.use(express.json({ limit: '10MB' }));\n\n const {\n logger: parentLogger,\n config,\n reader,\n database,\n catalogClient,\n actions,\n scheduler,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n additionalWorkspaceProviders,\n permissions,\n permissionRules,\n autocompleteHandlers = {},\n events: eventsService,\n auth,\n httpAuth,\n auditor,\n } = options;\n\n const concurrentTasksLimit =\n options.concurrentTasksLimit ??\n options.config.getOptionalNumber('scaffolder.concurrentTasksLimit');\n\n const logger = parentLogger.child({ plugin: 'scaffolder' });\n\n const workingDirectory = await getWorkingDirectory(config, logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n let taskBroker: TaskBroker;\n if (!options.taskBroker) {\n const databaseTaskStore = await DatabaseTaskStore.create({\n database,\n events: eventsService,\n });\n taskBroker = new StorageTaskBroker(\n databaseTaskStore,\n logger,\n config,\n auth,\n additionalWorkspaceProviders,\n auditor,\n );\n\n if (scheduler && databaseTaskStore.listStaleTasks) {\n await scheduler.scheduleTask({\n id: 'close_stale_tasks',\n frequency: readDuration(\n config,\n 'scaffolder.taskTimeoutJanitorFrequency',\n {\n minutes: 5,\n },\n ),\n timeout: { minutes: 15 },\n fn: async () => {\n const { tasks } = await databaseTaskStore.listStaleTasks({\n timeoutS: Duration.fromObject(\n readDuration(config, 'scaffolder.taskTimeout', {\n hours: 24,\n }),\n ).as('seconds'),\n });\n\n for (const task of tasks) {\n await databaseTaskStore.shutdownTask(task);\n logger.info(`Successfully closed stale task ${task.taskId}`);\n }\n },\n });\n }\n } else {\n taskBroker = options.taskBroker;\n }\n\n const actionRegistry = new TemplateActionRegistry();\n\n const templateExtensions = {\n additionalTemplateFilters: convertFiltersToRecord(\n additionalTemplateFilters,\n ),\n additionalTemplateGlobals: convertGlobalsToRecord(\n additionalTemplateGlobals,\n ),\n };\n\n const workers: TaskWorker[] = [];\n if (concurrentTasksLimit !== 0) {\n const gracefulShutdown = config.getOptionalBoolean(\n 'scaffolder.EXPERIMENTAL_gracefulShutdown',\n );\n\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n concurrentTasksLimit,\n permissions,\n gracefulShutdown,\n ...templateExtensions,\n });\n\n workers.push(worker);\n }\n\n const actionsToRegister = Array.isArray(actions)\n ? actions\n : createBuiltinActions({\n integrations,\n catalogClient,\n reader,\n config,\n auth,\n ...templateExtensions,\n });\n\n actionsToRegister.forEach(action => actionRegistry.register(action));\n\n const launchWorkers = () => workers.forEach(worker => worker.start());\n\n const shutdownWorkers = async () => {\n await Promise.allSettled(workers.map(worker => worker.stop()));\n };\n\n if (options.lifecycle) {\n options.lifecycle.addStartupHook(launchWorkers);\n options.lifecycle.addShutdownHook(shutdownWorkers);\n } else {\n launchWorkers();\n }\n\n const dryRunner = createDryRunner({\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n permissions,\n ...templateExtensions,\n });\n\n const templateRules: TemplatePermissionRuleInput[] = Object.values(\n scaffolderTemplateRules,\n );\n const actionRules: ActionPermissionRuleInput[] = Object.values(\n scaffolderActionRules,\n );\n\n if (permissionRules) {\n templateRules.push(\n ...permissionRules.filter(isTemplatePermissionRuleInput),\n );\n actionRules.push(...permissionRules.filter(isActionPermissionRuleInput));\n }\n\n const isAuthorized = createConditionAuthorizer(Object.values(templateRules));\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n resources: [\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n permissions: scaffolderTemplatePermissions,\n rules: templateRules,\n },\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n permissions: scaffolderActionPermissions,\n rules: actionRules,\n },\n ],\n permissions: scaffolderPermissions,\n });\n\n router.use(permissionIntegrationRouter);\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const requestedTemplateRef = `${req.params.kind}:${req.params.namespace}/${req.params.name}`;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'template-parameter-schema',\n request: req,\n meta: { templateRef: requestedTemplateRef },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const template = await authorizeTemplate(\n req.params,\n token,\n credentials,\n );\n\n const parameters = [template.spec.parameters ?? []].flat();\n\n const presentation = template.spec.presentation;\n\n const templateRef = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n await auditorEvent?.success({ meta: { templateRef: templateRef } });\n\n res.json({\n title: template.metadata.title ?? template.metadata.name,\n ...(presentation ? { presentation } : {}),\n description: template.metadata.description,\n 'ui:options': template.metadata['ui:options'],\n steps: parameters.map(schema => ({\n title: schema.title ?? 'Please enter the following information',\n description: schema.description,\n schema,\n })),\n EXPERIMENTAL_formDecorators:\n template.spec.EXPERIMENTAL_formDecorators,\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n },\n )\n .get('/v2/actions', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'action-fetch',\n request: req,\n });\n\n try {\n const actionsList = actionRegistry.list().map(action => {\n return {\n id: action.id,\n description: action.description,\n examples: action.examples,\n schema: action.schema,\n };\n });\n\n await auditorEvent?.success();\n\n res.json(actionsList);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks', async (req, res) => {\n const templateRef: string = req.body.templateRef;\n const { kind, namespace, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'create',\n templateRef: templateRef,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\n : undefined;\n\n let auditLog = `Scaffolding task for ${templateRef}`;\n if (userEntityRef) {\n auditLog += ` created by ${userEntityRef}`;\n }\n logger.info(auditLog);\n\n const values = req.body.values;\n\n const template = await authorizeTemplate(\n { kind, namespace, name },\n token,\n credentials,\n );\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(values, parameters);\n\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not create entity',\n ),\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const baseUrl = getEntityBaseUrl(template);\n\n const taskSpec: TaskSpec = {\n apiVersion: template.apiVersion,\n steps: template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n })),\n EXPERIMENTAL_recovery: template.spec.EXPERIMENTAL_recovery,\n output: template.spec.output ?? {},\n parameters: values,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n templateInfo: {\n entityRef: stringifyEntityRef({ kind, name, namespace }),\n baseUrl,\n entity: {\n metadata: template.metadata,\n },\n },\n };\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n const result = await taskBroker.dispatch({\n spec: taskSpec,\n createdBy: userEntityRef,\n secrets,\n });\n\n await auditorEvent?.success({ meta: { taskId: result.taskId } });\n\n res.status(201).json({ id: result.taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'list',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n if (!taskBroker.list) {\n throw new Error(\n 'TaskBroker does not support listing tasks, please implement the list method on the TaskBroker.',\n );\n }\n\n const createdBy = parseStringsParam(req.query.createdBy, 'createdBy');\n const status = parseStringsParam(req.query.status, 'status');\n\n const order = parseStringsParam(req.query.order, 'order')?.map(item => {\n const match = item.match(/^(asc|desc):(.+)$/);\n if (!match) {\n throw new InputError(\n `Invalid order parameter \"${item}\", expected \"<asc or desc>:<field name>\"`,\n );\n }\n\n return {\n order: match[1] as 'asc' | 'desc',\n field: match[2],\n };\n });\n\n const limit = parseNumberParam(req.query.limit, 'limit');\n const offset = parseNumberParam(req.query.offset, 'offset');\n\n const tasks = await taskBroker.list({\n filters: {\n createdBy,\n status: status ? (status as TaskStatus[]) : undefined,\n },\n order,\n pagination: {\n limit: limit ? limit[0] : undefined,\n offset: offset ? offset[0] : undefined,\n },\n });\n\n await auditorEvent?.success();\n\n res.status(200).json(tasks);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'get',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const task = await taskBroker.get(taskId);\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n\n await auditorEvent?.success();\n\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/cancel', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'cancel',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCancelPermission, taskReadPermission],\n permissionService: permissions,\n });\n\n await taskBroker.cancel?.(taskId);\n\n await auditorEvent?.success();\n\n res.status(200).json({ status: 'cancelled' });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/retry', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'retry',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission, taskReadPermission],\n permissionService: permissions,\n });\n\n await auditorEvent?.success();\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n await taskBroker.retry?.({ secrets, taskId });\n res.status(201).json({ id: taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId/eventstream', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'stream',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n logger.debug(`Event stream observing taskId '${taskId}' opened`);\n\n // Mandatory headers and http status to keep connection open\n res.writeHead(200, {\n Connection: 'keep-alive',\n 'Cache-Control': 'no-cache',\n 'Content-Type': 'text/event-stream',\n });\n\n // After client opens connection send all events as string\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n res.end();\n },\n next: ({ events }) => {\n let shouldUnsubscribe = false;\n for (const event of events) {\n res.write(\n `event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n if (event.type === 'completion' && !event.isTaskRecoverable) {\n shouldUnsubscribe = true;\n }\n }\n // res.flush() is only available with the compression middleware\n res.flush?.();\n if (shouldUnsubscribe) {\n subscription.unsubscribe();\n res.end();\n }\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', async () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n await auditorEvent?.success();\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'events',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const after = Number(req.query.after) || undefined;\n\n // cancel the request after 30 seconds. this aligns with the recommendations of RFC 6202.\n const timeout = setTimeout(() => {\n res.json([]);\n }, 30_000);\n\n // Get all known events after an id (always includes the completion event) and return the first callback\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n },\n next: async ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\n await auditorEvent?.success();\n res.json(events);\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n clearTimeout(timeout);\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/dry-run', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'dry-run',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const bodySchema = z.object({\n template: z.unknown(),\n values: z.record(z.unknown()),\n secrets: z.record(z.string()).optional(),\n directoryContents: z.array(\n z.object({ path: z.string(), base64Content: z.string() }),\n ),\n });\n const body = await bodySchema.parseAsync(req.body).catch(e => {\n throw new InputError(`Malformed request: ${e}`);\n });\n\n const template = body.template as TemplateEntityV1beta3;\n if (!(await templateEntityV1beta3Validator.check(template))) {\n throw new InputError('Input template is not a template');\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\n : undefined;\n\n const templateRef: string = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(body.values, parameters);\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not execute dry run',\n ),\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const steps = template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n }));\n\n const dryRunId = uuid();\n const contentsPath = resolveSafeChildPath(\n workingDirectory,\n `dry-run-content-${dryRunId}`,\n );\n const templateInfo = {\n entityRef: 'template:default/dry-run',\n entity: {\n metadata: template.metadata,\n },\n baseUrl: pathToFileURL(\n resolveSafeChildPath(contentsPath, 'template.yaml'),\n ).toString(),\n };\n\n const result = await dryRunner({\n spec: {\n apiVersion: template.apiVersion,\n steps,\n output: template.spec.output ?? {},\n parameters: body.values as JsonObject,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n },\n templateInfo: templateInfo,\n directoryContents: (body.directoryContents ?? []).map(file => ({\n path: file.path,\n content: Buffer.from(file.base64Content, 'base64'),\n })),\n secrets: {\n ...body.secrets,\n ...(token && { backstageToken: token }),\n },\n credentials,\n });\n\n await auditorEvent?.success({\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(200).json({\n ...result,\n steps,\n directoryContents: result.directoryContents.map(file => ({\n path: file.path,\n executable: file.executable,\n base64Content: file.content.toString('base64'),\n })),\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/autocomplete/:provider/:resource', async (req, res) => {\n const { token, context } = req.body;\n const { provider, resource } = req.params;\n\n if (!token) throw new InputError('Missing token query parameter');\n\n if (!autocompleteHandlers[provider]) {\n throw new InputError(`Unsupported provider: ${provider}`);\n }\n\n const { results } = await autocompleteHandlers[provider]({\n resource,\n token,\n context,\n });\n\n res.status(200).json({ results });\n })\n .get('/v2/templating-extensions', async (_req, res) => {\n res.status(200).json({\n filters: {\n ...extractFilterMetadata(createDefaultFilters({ integrations })),\n ...extractFilterMetadata(additionalTemplateFilters),\n },\n globals: {\n functions: extractGlobalFunctionMetadata(additionalTemplateGlobals),\n values: extractGlobalValueMetadata(additionalTemplateGlobals),\n },\n });\n });\n\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n async function authorizeTemplate(\n entityRef: CompoundEntityRef,\n token: string | undefined,\n credentials: BackstageCredentials,\n ) {\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef,\n token,\n });\n\n if (!isSupportedTemplate(template)) {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n\n if (!permissions) {\n return template;\n }\n\n const [parameterDecision, stepDecision] =\n await permissions.authorizeConditional(\n [\n { permission: templateParameterReadPermission },\n { permission: templateStepReadPermission },\n ],\n { credentials },\n );\n\n // Authorize parameters\n if (Array.isArray(template.spec.parameters)) {\n template.spec.parameters = template.spec.parameters.filter(step =>\n isAuthorized(parameterDecision, step),\n );\n } else if (\n template.spec.parameters &&\n !isAuthorized(parameterDecision, template.spec.parameters)\n ) {\n template.spec.parameters = undefined;\n }\n\n // Authorize steps\n template.spec.steps = template.spec.steps.filter(step =>\n isAuthorized(stepDecision, step),\n );\n\n return template;\n }\n\n return app;\n}\n"],"names":["config","readDurationFromConfig","Router","express","permissions","getWorkingDirectory","ScmIntegrations","DatabaseTaskStore","StorageTaskBroker","Duration","TemplateActionRegistry","convertFiltersToRecord","convertGlobalsToRecord","TaskWorker","createBuiltinActions","createDryRunner","scaffolderTemplateRules","scaffolderActionRules","isTemplatePermissionRuleInput","isActionPermissionRuleInput","createConditionAuthorizer","createPermissionIntegrationRouter","RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","scaffolderTemplatePermissions","RESOURCE_TYPE_SCAFFOLDER_ACTION","scaffolderActionPermissions","scaffolderPermissions","parseEntityRef","checkPermission","taskCreatePermission","result","validate","getEntityBaseUrl","stringifyEntityRef","taskReadPermission","parseStringsParam","InputError","parseNumberParam","NotFoundError","taskCancelPermission","z","templateEntityV1beta3Validator","uuid","resolveSafeChildPath","pathToFileURL","extractFilterMetadata","createDefaultFilters","extractGlobalFunctionMetadata","extractGlobalValueMetadata","findTemplate","templateParameterReadPermission","templateStepReadPermission"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0JA,SAAS,oBAAoB,MAA+B,EAAA;AAC1D,EAAA,OAAO,OAAO,UAAe,KAAA,iCAAA;AAC/B;AAEA,MAAM,YAAe,GAAA,CACnBA,QACA,EAAA,GAAA,EACA,YACG,KAAA;AACH,EAAI,IAAAA,QAAA,CAAO,GAAI,CAAA,GAAG,CAAG,EAAA;AACnB,IAAA,OAAOC,6BAAuB,CAAAD,QAAA,EAAQ,EAAE,GAAA,EAAK,CAAA;AAAA;AAE/C,EAAO,OAAA,YAAA;AACT,CAAA;AAKA,eAAsB,aACpB,OACyB,EAAA;AACzB,EAAA,MAAM,SAASE,uBAAO,EAAA;AAEtB,EAAA,MAAA,CAAO,IAAIC,wBAAQ,CAAA,IAAA,CAAK,EAAE,KAAO,EAAA,MAAA,EAAQ,CAAC,CAAA;AAE1C,EAAM,MAAA;AAAA,IACJ,MAAQ,EAAA,YAAA;AAAA,IACR,MAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,IACA,aAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,yBAAA;AAAA,IACA,yBAAA;AAAA,IACA,4BAAA;AAAA,iBACAC,aAAA;AAAA,IACA,eAAA;AAAA,IACA,uBAAuB,EAAC;AAAA,IACxB,MAAQ,EAAA,aAAA;AAAA,IACR,IAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACE,GAAA,OAAA;AAEJ,EAAA,MAAM,uBACJ,OAAQ,CAAA,oBAAA,IACR,OAAQ,CAAA,MAAA,CAAO,kBAAkB,iCAAiC,CAAA;AAEpE,EAAA,MAAM,SAAS,YAAa,CAAA,KAAA,CAAM,EAAE,MAAA,EAAQ,cAAc,CAAA;AAE1D,EAAA,MAAM,gBAAmB,GAAA,MAAMC,2BAAoB,CAAA,MAAA,EAAQ,MAAM,CAAA;AACjE,EAAM,MAAA,YAAA,GAAeC,2BAAgB,CAAA,UAAA,CAAW,MAAM,CAAA;AAEtD,EAAI,IAAA,UAAA;AACJ,EAAI,IAAA,CAAC,QAAQ,UAAY,EAAA;AACvB,IAAM,MAAA,iBAAA,GAAoB,MAAMC,mCAAA,CAAkB,MAAO,CAAA;AAAA,MACvD,QAAA;AAAA,MACA,MAAQ,EAAA;AAAA,KACT,CAAA;AACD,IAAA,UAAA,GAAa,IAAIC,mCAAA;AAAA,MACf,iBAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA;AAAA,MACA,4BAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAI,IAAA,SAAA,IAAa,kBAAkB,cAAgB,EAAA;AACjD,MAAA,MAAM,UAAU,YAAa,CAAA;AAAA,QAC3B,EAAI,EAAA,mBAAA;AAAA,QACJ,SAAW,EAAA,YAAA;AAAA,UACT,MAAA;AAAA,UACA,wCAAA;AAAA,UACA;AAAA,YACE,OAAS,EAAA;AAAA;AACX,SACF;AAAA,QACA,OAAA,EAAS,EAAE,OAAA,EAAS,EAAG,EAAA;AAAA,QACvB,IAAI,YAAY;AACd,UAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,kBAAkB,cAAe,CAAA;AAAA,YACvD,UAAUC,cAAS,CAAA,UAAA;AAAA,cACjB,YAAA,CAAa,QAAQ,wBAA0B,EAAA;AAAA,gBAC7C,KAAO,EAAA;AAAA,eACR;AAAA,aACH,CAAE,GAAG,SAAS;AAAA,WACf,CAAA;AAED,UAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,YAAM,MAAA,iBAAA,CAAkB,aAAa,IAAI,CAAA;AACzC,YAAA,MAAA,CAAO,IAAK,CAAA,CAAA,+BAAA,EAAkC,IAAK,CAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AAC7D;AACF,OACD,CAAA;AAAA;AACH,GACK,MAAA;AACL,IAAA,UAAA,GAAa,OAAQ,CAAA,UAAA;AAAA;AAGvB,EAAM,MAAA,cAAA,GAAiB,IAAIC,6CAAuB,EAAA;AAElD,EAAA,MAAM,kBAAqB,GAAA;AAAA,IACzB,yBAA2B,EAAAC,iCAAA;AAAA,MACzB;AAAA,KACF;AAAA,IACA,yBAA2B,EAAAC,iCAAA;AAAA,MACzB;AAAA;AACF,GACF;AAEA,EAAA,MAAM,UAAwB,EAAC;AAC/B,EAAA,IAAI,yBAAyB,CAAG,EAAA;AAC9B,IAAA,MAAM,mBAAmB,MAAO,CAAA,kBAAA;AAAA,MAC9B;AAAA,KACF;AAEA,IAAM,MAAA,MAAA,GAAS,MAAMC,qBAAA,CAAW,MAAO,CAAA;AAAA,MACrC,UAAA;AAAA,MACA,cAAA;AAAA,MACA,YAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,gBAAA;AAAA,MACA,oBAAA;AAAA,mBACAT,aAAA;AAAA,MACA,gBAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAED,IAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA;AAGrB,EAAA,MAAM,oBAAoB,KAAM,CAAA,OAAA,CAAQ,OAAO,CAAA,GAC3C,UACAU,yCAAqB,CAAA;AAAA,IACnB,YAAA;AAAA,IACA,aAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AAEL,EAAA,iBAAA,CAAkB,OAAQ,CAAA,CAAA,MAAA,KAAU,cAAe,CAAA,QAAA,CAAS,MAAM,CAAC,CAAA;AAEnE,EAAA,MAAM,gBAAgB,MAAM,OAAA,CAAQ,QAAQ,CAAU,MAAA,KAAA,MAAA,CAAO,OAAO,CAAA;AAEpE,EAAA,MAAM,kBAAkB,YAAY;AAClC,IAAM,MAAA,OAAA,CAAQ,WAAW,OAAQ,CAAA,GAAA,CAAI,YAAU,MAAO,CAAA,IAAA,EAAM,CAAC,CAAA;AAAA,GAC/D;AAEA,EAAA,IAAI,QAAQ,SAAW,EAAA;AACrB,IAAQ,OAAA,CAAA,SAAA,CAAU,eAAe,aAAa,CAAA;AAC9C,IAAQ,OAAA,CAAA,SAAA,CAAU,gBAAgB,eAAe,CAAA;AAAA,GAC5C,MAAA;AACL,IAAc,aAAA,EAAA;AAAA;AAGhB,EAAA,MAAM,YAAYC,+BAAgB,CAAA;AAAA,IAChC,cAAA;AAAA,IACA,YAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,gBAAA;AAAA,iBACAX,aAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AAED,EAAA,MAAM,gBAA+C,MAAO,CAAA,MAAA;AAAA,IAC1DY;AAAA,GACF;AACA,EAAA,MAAM,cAA2C,MAAO,CAAA,MAAA;AAAA,IACtDC;AAAA,GACF;AAEA,EAAA,IAAI,eAAiB,EAAA;AACnB,IAAc,aAAA,CAAA,IAAA;AAAA,MACZ,GAAG,eAAgB,CAAA,MAAA,CAAOC,yCAA6B;AAAA,KACzD;AACA,IAAA,WAAA,CAAY,IAAK,CAAA,GAAG,eAAgB,CAAA,MAAA,CAAOC,uCAA2B,CAAC,CAAA;AAAA;AAGzE,EAAA,MAAM,YAAe,GAAAC,8CAAA,CAA0B,MAAO,CAAA,MAAA,CAAO,aAAa,CAAC,CAAA;AAE3E,EAAA,MAAM,8BAA8BC,sDAAkC,CAAA;AAAA,IACpE,SAAW,EAAA;AAAA,MACT;AAAA,QACE,YAAc,EAAAC,uCAAA;AAAA,QACd,WAAa,EAAAC,mCAAA;AAAA,QACb,KAAO,EAAA;AAAA,OACT;AAAA,MACA;AAAA,QACE,YAAc,EAAAC,qCAAA;AAAA,QACd,WAAa,EAAAC,iCAAA;AAAA,QACb,KAAO,EAAA;AAAA;AACT,KACF;AAAA,IACA,WAAa,EAAAC;AAAA,GACd,CAAA;AAED,EAAA,MAAA,CAAO,IAAI,2BAA2B,CAAA;AAEtC,EACG,MAAA,CAAA,GAAA;AAAA,IACC,uDAAA;AAAA,IACA,OAAO,KAAK,GAAQ,KAAA;AAClB,MAAA,MAAM,oBAAuB,GAAA,CAAA,EAAG,GAAI,CAAA,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,GAAI,CAAA,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,GAAI,CAAA,MAAA,CAAO,IAAI,CAAA,CAAA;AAE1F,MAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,QAC9C,OAAS,EAAA,2BAAA;AAAA,QACT,OAAS,EAAA,GAAA;AAAA,QACT,IAAA,EAAM,EAAE,WAAA,EAAa,oBAAqB;AAAA,OAC3C,CAAA;AAED,MAAI,IAAA;AACF,QAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAElD,QAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,KAAK,qBAAsB,CAAA;AAAA,UACjD,UAAY,EAAA,WAAA;AAAA,UACZ,cAAgB,EAAA;AAAA,SACjB,CAAA;AAED,QAAA,MAAM,WAAW,MAAM,iBAAA;AAAA,UACrB,GAAI,CAAA,MAAA;AAAA,UACJ,KAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAM,MAAA,UAAA,GAAa,CAAC,QAAS,CAAA,IAAA,CAAK,cAAc,EAAE,EAAE,IAAK,EAAA;AAEzD,QAAM,MAAA,YAAA,GAAe,SAAS,IAAK,CAAA,YAAA;AAEnC,QAAA,MAAM,WAAc,GAAA,CAAA,EAAG,QAAS,CAAA,IAAI,CAClC,CAAA,EAAA,QAAA,CAAS,QAAS,CAAA,SAAA,IAAa,SACjC,CAAA,CAAA,EAAI,QAAS,CAAA,QAAA,CAAS,IAAI,CAAA,CAAA;AAE1B,QAAA,MAAM,cAAc,OAAQ,CAAA,EAAE,MAAM,EAAE,WAAA,IAA4B,CAAA;AAElE,QAAA,GAAA,CAAI,IAAK,CAAA;AAAA,UACP,KAAO,EAAA,QAAA,CAAS,QAAS,CAAA,KAAA,IAAS,SAAS,QAAS,CAAA,IAAA;AAAA,UACpD,GAAI,YAAA,GAAe,EAAE,YAAA,KAAiB,EAAC;AAAA,UACvC,WAAA,EAAa,SAAS,QAAS,CAAA,WAAA;AAAA,UAC/B,YAAA,EAAc,QAAS,CAAA,QAAA,CAAS,YAAY,CAAA;AAAA,UAC5C,KAAA,EAAO,UAAW,CAAA,GAAA,CAAI,CAAW,MAAA,MAAA;AAAA,YAC/B,KAAA,EAAO,OAAO,KAAS,IAAA,wCAAA;AAAA,YACvB,aAAa,MAAO,CAAA,WAAA;AAAA,YACpB;AAAA,WACA,CAAA,CAAA;AAAA,UACF,2BAAA,EACE,SAAS,IAAK,CAAA;AAAA,SACjB,CAAA;AAAA,eACM,GAAK,EAAA;AACZ,QAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,QAAM,MAAA,GAAA;AAAA;AACR;AACF,GAED,CAAA,GAAA,CAAI,aAAe,EAAA,OAAO,KAAK,GAAQ,KAAA;AACtC,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,cAAA;AAAA,MACT,OAAS,EAAA;AAAA,KACV,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,cAAA,CAAe,IAAK,EAAA,CAAE,IAAI,CAAU,MAAA,KAAA;AACtD,QAAO,OAAA;AAAA,UACL,IAAI,MAAO,CAAA,EAAA;AAAA,UACX,aAAa,MAAO,CAAA,WAAA;AAAA,UACpB,UAAU,MAAO,CAAA,QAAA;AAAA,UACjB,QAAQ,MAAO,CAAA;AAAA,SACjB;AAAA,OACD,CAAA;AAED,MAAA,MAAM,cAAc,OAAQ,EAAA;AAE5B,MAAA,GAAA,CAAI,KAAK,WAAW,CAAA;AAAA,aACb,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,IAAA,CAAK,WAAa,EAAA,OAAO,KAAK,GAAQ,KAAA;AACrC,IAAM,MAAA,WAAA,GAAsB,IAAI,IAAK,CAAA,WAAA;AACrC,IAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA,GAAIC,4BAAe,WAAa,EAAA;AAAA,MAC5D,WAAa,EAAA;AAAA,KACd,CAAA;AAED,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA,QAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAMC,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACC,0BAAoB,CAAA;AAAA,QAClC,iBAAmB,EAAAzB;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,KAAK,qBAAsB,CAAA;AAAA,QACjD,UAAY,EAAA,WAAA;AAAA,QACZ,cAAgB,EAAA;AAAA,OACjB,CAAA;AAED,MAAM,MAAA,aAAA,GAAgB,KAAK,WAAY,CAAA,WAAA,EAAa,MAAM,CACtD,GAAA,WAAA,CAAY,UAAU,aACtB,GAAA,KAAA,CAAA;AAEJ,MAAM,MAAA,UAAA,GAAa,gBACf,MAAM,aAAA,CAAc,eAAe,aAAe,EAAA,EAAE,KAAM,EAAC,CAC3D,GAAA,KAAA,CAAA;AAEJ,MAAI,IAAA,QAAA,GAAW,wBAAwB,WAAW,CAAA,CAAA;AAClD,MAAA,IAAI,aAAe,EAAA;AACjB,QAAA,QAAA,IAAY,eAAe,aAAa,CAAA,CAAA;AAAA;AAE1C,MAAA,MAAA,CAAO,KAAK,QAAQ,CAAA;AAEpB,MAAM,MAAA,MAAA,GAAS,IAAI,IAAK,CAAA,MAAA;AAExB,MAAA,MAAM,WAAW,MAAM,iBAAA;AAAA,QACrB,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA;AAAA,QACxB,KAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAW,KAAA,MAAA,UAAA,IAAc,CAAC,QAAS,CAAA,IAAA,CAAK,cAAc,EAAE,CAAE,CAAA,IAAA,EAAQ,EAAA;AAChE,QAAM0B,MAAAA,OAAAA,GAASC,mBAAS,CAAA,MAAA,EAAQ,UAAU,CAAA;AAE1C,QAAI,IAAA,CAACD,QAAO,KAAO,EAAA;AACjB,UAAA,MAAM,cAAc,IAAK,CAAA;AAAA;AAAA,YAEvB,KAAQ,EAAA,cAAA;AAAA,cACNA,OAAO,CAAA,MAAA;AAAA,cACP;AAAA;AACF,WACD,CAAA;AAED,UAAI,GAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQA,EAAAA,OAAAA,CAAO,QAAQ,CAAA;AAC9C,UAAA;AAAA;AACF;AAGF,MAAM,MAAA,OAAA,GAAUE,yBAAiB,QAAQ,CAAA;AAEzC,MAAA,MAAM,QAAqB,GAAA;AAAA,QACzB,YAAY,QAAS,CAAA,UAAA;AAAA,QACrB,OAAO,QAAS,CAAA,IAAA,CAAK,MAAM,GAAI,CAAA,CAAC,MAAM,KAAW,MAAA;AAAA,UAC/C,GAAG,IAAA;AAAA,UACH,EAAI,EAAA,IAAA,CAAK,EAAM,IAAA,CAAA,KAAA,EAAQ,QAAQ,CAAC,CAAA,CAAA;AAAA,UAChC,IAAA,EAAM,IAAK,CAAA,IAAA,IAAQ,IAAK,CAAA;AAAA,SACxB,CAAA,CAAA;AAAA,QACF,qBAAA,EAAuB,SAAS,IAAK,CAAA,qBAAA;AAAA,QACrC,MAAQ,EAAA,QAAA,CAAS,IAAK,CAAA,MAAA,IAAU,EAAC;AAAA,QACjC,UAAY,EAAA,MAAA;AAAA,QACZ,IAAM,EAAA;AAAA,UACJ,MAAQ,EAAA,UAAA;AAAA,UACR,GAAK,EAAA;AAAA,SACP;AAAA,QACA,YAAc,EAAA;AAAA,UACZ,WAAWC,+BAAmB,CAAA,EAAE,IAAM,EAAA,IAAA,EAAM,WAAW,CAAA;AAAA,UACvD,OAAA;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,UAAU,QAAS,CAAA;AAAA;AACrB;AACF,OACF;AAEA,MAAA,MAAM,OAA+B,GAAA;AAAA,QACnC,GAAG,IAAI,IAAK,CAAA,OAAA;AAAA,QACZ,cAAgB,EAAA,KAAA;AAAA,QAChB,sBAAA,EAAwB,KAAK,SAAU,CAAA;AAAA,UACrC,GAAG,WAAA;AAAA;AAAA,UAEH,OAAQ,WAAoB,CAAA;AAAA,SAC7B;AAAA,OACH;AAEA,MAAM,MAAA,MAAA,GAAS,MAAM,UAAA,CAAW,QAAS,CAAA;AAAA,QACvC,IAAM,EAAA,QAAA;AAAA,QACN,SAAW,EAAA,aAAA;AAAA,QACX;AAAA,OACD,CAAA;AAED,MAAM,MAAA,YAAA,EAAc,QAAQ,EAAE,IAAA,EAAM,EAAE,MAAQ,EAAA,MAAA,CAAO,MAAO,EAAA,EAAG,CAAA;AAE/D,MAAI,GAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,EAAI,EAAA,MAAA,CAAO,QAAQ,CAAA;AAAA,aACnC,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,GAAA,CAAI,WAAa,EAAA,OAAO,KAAK,GAAQ,KAAA;AACpC,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA;AAAA;AACd,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAML,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACM,wBAAkB,CAAA;AAAA,QAChC,iBAAmB,EAAA9B;AAAA,OACpB,CAAA;AAED,MAAI,IAAA,CAAC,WAAW,IAAM,EAAA;AACpB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SACF;AAAA;AAGF,MAAA,MAAM,SAAY,GAAA+B,yBAAA,CAAkB,GAAI,CAAA,KAAA,CAAM,WAAW,WAAW,CAAA;AACpE,MAAA,MAAM,MAAS,GAAAA,yBAAA,CAAkB,GAAI,CAAA,KAAA,CAAM,QAAQ,QAAQ,CAAA;AAE3D,MAAM,MAAA,KAAA,GAAQA,0BAAkB,GAAI,CAAA,KAAA,CAAM,OAAO,OAAO,CAAA,EAAG,IAAI,CAAQ,IAAA,KAAA;AACrE,QAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,KAAA,CAAM,mBAAmB,CAAA;AAC5C,QAAA,IAAI,CAAC,KAAO,EAAA;AACV,UAAA,MAAM,IAAIC,iBAAA;AAAA,YACR,4BAA4B,IAAI,CAAA,wCAAA;AAAA,WAClC;AAAA;AAGF,QAAO,OAAA;AAAA,UACL,KAAA,EAAO,MAAM,CAAC,CAAA;AAAA,UACd,KAAA,EAAO,MAAM,CAAC;AAAA,SAChB;AAAA,OACD,CAAA;AAED,MAAA,MAAM,KAAQ,GAAAC,wBAAA,CAAiB,GAAI,CAAA,KAAA,CAAM,OAAO,OAAO,CAAA;AACvD,MAAA,MAAM,MAAS,GAAAA,wBAAA,CAAiB,GAAI,CAAA,KAAA,CAAM,QAAQ,QAAQ,CAAA;AAE1D,MAAM,MAAA,KAAA,GAAQ,MAAM,UAAA,CAAW,IAAK,CAAA;AAAA,QAClC,OAAS,EAAA;AAAA,UACP,SAAA;AAAA,UACA,MAAA,EAAQ,SAAU,MAA0B,GAAA,KAAA;AAAA,SAC9C;AAAA,QACA,KAAA;AAAA,QACA,UAAY,EAAA;AAAA,UACV,KAAO,EAAA,KAAA,GAAQ,KAAM,CAAA,CAAC,CAAI,GAAA,KAAA,CAAA;AAAA,UAC1B,MAAQ,EAAA,MAAA,GAAS,MAAO,CAAA,CAAC,CAAI,GAAA,KAAA;AAAA;AAC/B,OACD,CAAA;AAED,MAAA,MAAM,cAAc,OAAQ,EAAA;AAE5B,MAAA,GAAA,CAAI,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA;AAAA,aACnB,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,GAAA,CAAI,mBAAqB,EAAA,OAAO,KAAK,GAAQ,KAAA;AAC5C,IAAM,MAAA,EAAE,MAAO,EAAA,GAAI,GAAI,CAAA,MAAA;AAEvB,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA,KAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAMT,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACM,wBAAkB,CAAA;AAAA,QAChC,iBAAmB,EAAA9B;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,IAAO,GAAA,MAAM,UAAW,CAAA,GAAA,CAAI,MAAM,CAAA;AACxC,MAAA,IAAI,CAAC,IAAM,EAAA;AACT,QAAA,MAAM,IAAIkC,oBAAA,CAAc,CAAgB,aAAA,EAAA,MAAM,CAAiB,eAAA,CAAA,CAAA;AAAA;AAGjE,MAAA,MAAM,cAAc,OAAQ,EAAA;AAG5B,MAAA,OAAO,IAAK,CAAA,OAAA;AACZ,MAAA,GAAA,CAAI,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA;AAAA,aAClB,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,IAAA,CAAK,0BAA4B,EAAA,OAAO,KAAK,GAAQ,KAAA;AACpD,IAAM,MAAA,EAAE,MAAO,EAAA,GAAI,GAAI,CAAA,MAAA;AAEvB,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA,QAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAElD,MAAA,MAAMV,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACW,0BAAA,EAAsBL,wBAAkB,CAAA;AAAA,QACtD,iBAAmB,EAAA9B;AAAA,OACpB,CAAA;AAED,MAAM,MAAA,UAAA,CAAW,SAAS,MAAM,CAAA;AAEhC,MAAA,MAAM,cAAc,OAAQ,EAAA;AAE5B,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,aAAa,CAAA;AAAA,aACrC,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,IAAA,CAAK,yBAA2B,EAAA,OAAO,KAAK,GAAQ,KAAA;AACnD,IAAM,MAAA,EAAE,MAAO,EAAA,GAAI,GAAI,CAAA,MAAA;AAEvB,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA,OAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAElD,MAAA,MAAMwB,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACC,0BAAA,EAAsBK,wBAAkB,CAAA;AAAA,QACtD,iBAAmB,EAAA9B;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,cAAc,OAAQ,EAAA;AAE5B,MAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,KAAK,qBAAsB,CAAA;AAAA,QACjD,UAAY,EAAA,WAAA;AAAA,QACZ,cAAgB,EAAA;AAAA,OACjB,CAAA;AAED,MAAA,MAAM,OAA+B,GAAA;AAAA,QACnC,GAAG,IAAI,IAAK,CAAA,OAAA;AAAA,QACZ,cAAgB,EAAA,KAAA;AAAA,QAChB,sBAAA,EAAwB,KAAK,SAAU,CAAA;AAAA,UACrC,GAAG,WAAA;AAAA;AAAA,UAEH,OAAQ,WAAoB,CAAA;AAAA,SAC7B;AAAA,OACH;AAEA,MAAA,MAAM,UAAW,CAAA,KAAA,GAAQ,EAAE,OAAA,EAAS,QAAQ,CAAA;AAC5C,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,EAAA,EAAI,QAAQ,CAAA;AAAA,aAC5B,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,GAAA,CAAI,+BAAiC,EAAA,OAAO,KAAK,GAAQ,KAAA;AACxD,IAAM,MAAA,EAAE,MAAO,EAAA,GAAI,GAAI,CAAA,MAAA;AAEvB,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA,QAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAMwB,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACM,wBAAkB,CAAA;AAAA,QAChC,iBAAmB,EAAA9B;AAAA,OACpB,CAAA;AAED,MAAM,MAAA,KAAA,GACJ,IAAI,KAAM,CAAA,KAAA,KAAU,SAAY,MAAO,CAAA,GAAA,CAAI,KAAM,CAAA,KAAK,CAAI,GAAA,KAAA,CAAA;AAE5D,MAAO,MAAA,CAAA,KAAA,CAAM,CAAkC,+BAAA,EAAA,MAAM,CAAU,QAAA,CAAA,CAAA;AAG/D,MAAA,GAAA,CAAI,UAAU,GAAK,EAAA;AAAA,QACjB,UAAY,EAAA,YAAA;AAAA,QACZ,eAAiB,EAAA,UAAA;AAAA,QACjB,cAAgB,EAAA;AAAA,OACjB,CAAA;AAGD,MAAM,MAAA,YAAA,GAAe,WAAW,MAAO,CAAA,EAAE,QAAQ,KAAM,EAAC,EAAE,SAAU,CAAA;AAAA,QAClE,KAAA,EAAO,OAAM,KAAS,KAAA;AACpB,UAAO,MAAA,CAAA,KAAA;AAAA,YACL,CAAA,wDAAA,EAA2D,MAAM,CAAA,GAAA,EAAM,KAAK,CAAA;AAAA,WAC9E;AACA,UAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAc,CAAA;AACzC,UAAA,GAAA,CAAI,GAAI,EAAA;AAAA,SACV;AAAA,QACA,IAAM,EAAA,CAAC,EAAE,MAAA,EAAa,KAAA;AACpB,UAAA,IAAI,iBAAoB,GAAA,KAAA;AACxB,UAAA,KAAA,MAAW,SAAS,MAAQ,EAAA;AAC1B,YAAI,GAAA,CAAA,KAAA;AAAA,cACF,CAAA,OAAA,EAAU,MAAM,IAAI;AAAA,MAAW,EAAA,IAAA,CAAK,SAAU,CAAA,KAAK,CAAC;;AAAA;AAAA,aACtD;AACA,YAAA,IAAI,KAAM,CAAA,IAAA,KAAS,YAAgB,IAAA,CAAC,MAAM,iBAAmB,EAAA;AAC3D,cAAoB,iBAAA,GAAA,IAAA;AAAA;AACtB;AAGF,UAAA,GAAA,CAAI,KAAQ,IAAA;AACZ,UAAA,IAAI,iBAAmB,EAAA;AACrB,YAAA,YAAA,CAAa,WAAY,EAAA;AACzB,YAAA,GAAA,CAAI,GAAI,EAAA;AAAA;AACV;AACF,OACD,CAAA;AAID,MAAI,GAAA,CAAA,EAAA,CAAG,SAAS,YAAY;AAC1B,QAAA,YAAA,CAAa,WAAY,EAAA;AACzB,QAAO,MAAA,CAAA,KAAA,CAAM,CAAkC,+BAAA,EAAA,MAAM,CAAU,QAAA,CAAA,CAAA;AAC/D,QAAA,MAAM,cAAc,OAAQ,EAAA;AAAA,OAC7B,CAAA;AAAA,aACM,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,GAAA,CAAI,0BAA4B,EAAA,OAAO,KAAK,GAAQ,KAAA;AACnD,IAAM,MAAA,EAAE,MAAO,EAAA,GAAI,GAAI,CAAA,MAAA;AAEvB,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA,QAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAMwB,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACM,wBAAkB,CAAA;AAAA,QAChC,iBAAmB,EAAA9B;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,KAAQ,GAAA,MAAA,CAAO,GAAI,CAAA,KAAA,CAAM,KAAK,CAAK,IAAA,KAAA,CAAA;AAGzC,MAAM,MAAA,OAAA,GAAU,WAAW,MAAM;AAC/B,QAAI,GAAA,CAAA,IAAA,CAAK,EAAE,CAAA;AAAA,SACV,GAAM,CAAA;AAGT,MAAM,MAAA,YAAA,GAAe,WAAW,MAAO,CAAA,EAAE,QAAQ,KAAM,EAAC,EAAE,SAAU,CAAA;AAAA,QAClE,KAAA,EAAO,OAAM,KAAS,KAAA;AACpB,UAAO,MAAA,CAAA,KAAA;AAAA,YACL,CAAA,wDAAA,EAA2D,MAAM,CAAA,GAAA,EAAM,KAAK,CAAA;AAAA,WAC9E;AACA,UAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAc,CAAA;AAAA,SAC3C;AAAA,QACA,IAAM,EAAA,OAAO,EAAE,MAAA,EAAa,KAAA;AAC1B,UAAA,YAAA,CAAa,OAAO,CAAA;AACpB,UAAA,YAAA,CAAa,WAAY,EAAA;AACzB,UAAA,MAAM,cAAc,OAAQ,EAAA;AAC5B,UAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA;AACjB,OACD,CAAA;AAID,MAAI,GAAA,CAAA,EAAA,CAAG,SAAS,MAAM;AACpB,QAAA,YAAA,CAAa,WAAY,EAAA;AACzB,QAAA,YAAA,CAAa,OAAO,CAAA;AAAA,OACrB,CAAA;AAAA,aACM,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,IAAA,CAAK,aAAe,EAAA,OAAO,KAAK,GAAQ,KAAA;AACvC,IAAM,MAAA,YAAA,GAAe,MAAM,OAAA,EAAS,WAAY,CAAA;AAAA,MAC9C,OAAS,EAAA,MAAA;AAAA,MACT,OAAS,EAAA,GAAA;AAAA,MACT,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA;AAAA;AACd,KACD,CAAA;AAED,IAAI,IAAA;AACF,MAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAMwB,gCAAgB,CAAA;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACC,0BAAoB,CAAA;AAAA,QAClC,iBAAmB,EAAAzB;AAAA,OACpB,CAAA;AAED,MAAM,MAAA,UAAA,GAAaoC,IAAE,MAAO,CAAA;AAAA,QAC1B,QAAA,EAAUA,IAAE,OAAQ,EAAA;AAAA,QACpB,MAAQ,EAAAA,GAAA,CAAE,MAAO,CAAAA,GAAA,CAAE,SAAS,CAAA;AAAA,QAC5B,SAASA,GAAE,CAAA,MAAA,CAAOA,IAAE,MAAO,EAAC,EAAE,QAAS,EAAA;AAAA,QACvC,mBAAmBA,GAAE,CAAA,KAAA;AAAA,UACnBA,GAAA,CAAE,MAAO,CAAA,EAAE,IAAM,EAAAA,GAAA,CAAE,MAAO,EAAA,EAAG,aAAe,EAAAA,GAAA,CAAE,MAAO,EAAA,EAAG;AAAA;AAC1D,OACD,CAAA;AACD,MAAM,MAAA,IAAA,GAAO,MAAM,UAAW,CAAA,UAAA,CAAW,IAAI,IAAI,CAAA,CAAE,MAAM,CAAK,CAAA,KAAA;AAC5D,QAAA,MAAM,IAAIJ,iBAAA,CAAW,CAAsB,mBAAA,EAAA,CAAC,CAAE,CAAA,CAAA;AAAA,OAC/C,CAAA;AAED,MAAA,MAAM,WAAW,IAAK,CAAA,QAAA;AACtB,MAAA,IAAI,CAAE,MAAMK,qDAA+B,CAAA,KAAA,CAAM,QAAQ,CAAI,EAAA;AAC3D,QAAM,MAAA,IAAIL,kBAAW,kCAAkC,CAAA;AAAA;AAGzD,MAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,KAAK,qBAAsB,CAAA;AAAA,QACjD,UAAY,EAAA,WAAA;AAAA,QACZ,cAAgB,EAAA;AAAA,OACjB,CAAA;AAED,MAAM,MAAA,aAAA,GAAgB,KAAK,WAAY,CAAA,WAAA,EAAa,MAAM,CACtD,GAAA,WAAA,CAAY,UAAU,aACtB,GAAA,KAAA,CAAA;AAEJ,MAAM,MAAA,UAAA,GAAa,gBACf,MAAM,aAAA,CAAc,eAAe,aAAe,EAAA,EAAE,KAAM,EAAC,CAC3D,GAAA,KAAA,CAAA;AAEJ,MAAA,MAAM,WAAsB,GAAA,CAAA,EAAG,QAAS,CAAA,IAAI,CAC1C,CAAA,EAAA,QAAA,CAAS,QAAS,CAAA,SAAA,IAAa,SACjC,CAAA,CAAA,EAAI,QAAS,CAAA,QAAA,CAAS,IAAI,CAAA,CAAA;AAE1B,MAAW,KAAA,MAAA,UAAA,IAAc,CAAC,QAAS,CAAA,IAAA,CAAK,cAAc,EAAE,CAAE,CAAA,IAAA,EAAQ,EAAA;AAChE,QAAA,MAAMN,OAAS,GAAAC,mBAAA,CAAS,IAAK,CAAA,MAAA,EAAQ,UAAU,CAAA;AAC/C,QAAI,IAAA,CAACD,QAAO,KAAO,EAAA;AACjB,UAAA,MAAM,cAAc,IAAK,CAAA;AAAA;AAAA,YAEvB,KAAQ,EAAA,cAAA;AAAA,cACNA,OAAO,CAAA,MAAA;AAAA,cACP;AAAA,aACF;AAAA,YACA,IAAM,EAAA;AAAA,cACJ,WAAA;AAAA,cACA,UAAA,EAAY,SAAS,IAAK,CAAA;AAAA;AAC5B,WACD,CAAA;AAED,UAAI,GAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQA,EAAAA,OAAAA,CAAO,QAAQ,CAAA;AAC9C,UAAA;AAAA;AACF;AAGF,MAAA,MAAM,QAAQ,QAAS,CAAA,IAAA,CAAK,MAAM,GAAI,CAAA,CAAC,MAAM,KAAW,MAAA;AAAA,QACtD,GAAG,IAAA;AAAA,QACH,EAAI,EAAA,IAAA,CAAK,EAAM,IAAA,CAAA,KAAA,EAAQ,QAAQ,CAAC,CAAA,CAAA;AAAA,QAChC,IAAA,EAAM,IAAK,CAAA,IAAA,IAAQ,IAAK,CAAA;AAAA,OACxB,CAAA,CAAA;AAEF,MAAA,MAAM,WAAWY,OAAK,EAAA;AACtB,MAAA,MAAM,YAAe,GAAAC,qCAAA;AAAA,QACnB,gBAAA;AAAA,QACA,mBAAmB,QAAQ,CAAA;AAAA,OAC7B;AACA,MAAA,MAAM,YAAe,GAAA;AAAA,QACnB,SAAW,EAAA,0BAAA;AAAA,QACX,MAAQ,EAAA;AAAA,UACN,UAAU,QAAS,CAAA;AAAA,SACrB;AAAA,QACA,OAAS,EAAAC,iBAAA;AAAA,UACPD,qCAAA,CAAqB,cAAc,eAAe;AAAA,UAClD,QAAS;AAAA,OACb;AAEA,MAAM,MAAA,MAAA,GAAS,MAAM,SAAU,CAAA;AAAA,QAC7B,IAAM,EAAA;AAAA,UACJ,YAAY,QAAS,CAAA,UAAA;AAAA,UACrB,KAAA;AAAA,UACA,MAAQ,EAAA,QAAA,CAAS,IAAK,CAAA,MAAA,IAAU,EAAC;AAAA,UACjC,YAAY,IAAK,CAAA,MAAA;AAAA,UACjB,IAAM,EAAA;AAAA,YACJ,MAAQ,EAAA,UAAA;AAAA,YACR,GAAK,EAAA;AAAA;AACP,SACF;AAAA,QACA,YAAA;AAAA,QACA,oBAAoB,IAAK,CAAA,iBAAA,IAAqB,EAAC,EAAG,IAAI,CAAS,IAAA,MAAA;AAAA,UAC7D,MAAM,IAAK,CAAA,IAAA;AAAA,UACX,OAAS,EAAA,MAAA,CAAO,IAAK,CAAA,IAAA,CAAK,eAAe,QAAQ;AAAA,SACjD,CAAA,CAAA;AAAA,QACF,OAAS,EAAA;AAAA,UACP,GAAG,IAAK,CAAA,OAAA;AAAA,UACR,GAAI,KAAA,IAAS,EAAE,cAAA,EAAgB,KAAM;AAAA,SACvC;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,cAAc,OAAQ,CAAA;AAAA,QAC1B,IAAM,EAAA;AAAA,UACJ,WAAA;AAAA,UACA,UAAA,EAAY,SAAS,IAAK,CAAA;AAAA;AAC5B,OACD,CAAA;AAED,MAAI,GAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,QACnB,GAAG,MAAA;AAAA,QACH,KAAA;AAAA,QACA,iBAAmB,EAAA,MAAA,CAAO,iBAAkB,CAAA,GAAA,CAAI,CAAS,IAAA,MAAA;AAAA,UACvD,MAAM,IAAK,CAAA,IAAA;AAAA,UACX,YAAY,IAAK,CAAA,UAAA;AAAA,UACjB,aAAe,EAAA,IAAA,CAAK,OAAQ,CAAA,QAAA,CAAS,QAAQ;AAAA,SAC7C,CAAA;AAAA,OACH,CAAA;AAAA,aACM,GAAK,EAAA;AACZ,MAAA,MAAM,YAAc,EAAA,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAM,MAAA,GAAA;AAAA;AACR,GACD,CACA,CAAA,IAAA,CAAK,sCAAwC,EAAA,OAAO,KAAK,GAAQ,KAAA;AAChE,IAAA,MAAM,EAAE,KAAA,EAAO,OAAQ,EAAA,GAAI,GAAI,CAAA,IAAA;AAC/B,IAAA,MAAM,EAAE,QAAA,EAAU,QAAS,EAAA,GAAI,GAAI,CAAA,MAAA;AAEnC,IAAA,IAAI,CAAC,KAAA,EAAa,MAAA,IAAIP,kBAAW,+BAA+B,CAAA;AAEhE,IAAI,IAAA,CAAC,oBAAqB,CAAA,QAAQ,CAAG,EAAA;AACnC,MAAA,MAAM,IAAIA,iBAAA,CAAW,CAAyB,sBAAA,EAAA,QAAQ,CAAE,CAAA,CAAA;AAAA;AAG1D,IAAA,MAAM,EAAE,OAAQ,EAAA,GAAI,MAAM,oBAAA,CAAqB,QAAQ,CAAE,CAAA;AAAA,MACvD,QAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,IAAK,CAAA,EAAE,SAAS,CAAA;AAAA,GACjC,CACA,CAAA,GAAA,CAAI,2BAA6B,EAAA,OAAO,MAAM,GAAQ,KAAA;AACrD,IAAI,GAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,MACnB,OAAS,EAAA;AAAA,QACP,GAAGS,gCAAsB,CAAAC,yCAAA,CAAqB,EAAE,YAAA,EAAc,CAAC,CAAA;AAAA,QAC/D,GAAGD,iCAAsB,yBAAyB;AAAA,OACpD;AAAA,MACA,OAAS,EAAA;AAAA,QACP,SAAA,EAAWE,yCAA8B,yBAAyB,CAAA;AAAA,QAClE,MAAA,EAAQC,sCAA2B,yBAAyB;AAAA;AAC9D,KACD,CAAA;AAAA,GACF,CAAA;AAEH,EAAA,MAAM,MAAM7C,wBAAQ,EAAA;AACpB,EAAI,GAAA,CAAA,GAAA,CAAI,UAAU,MAAM,CAAA;AACxB,EAAI,GAAA,CAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAEnB,EAAe,eAAA,iBAAA,CACb,SACA,EAAA,KAAA,EACA,WACA,EAAA;AACA,IAAM,MAAA,QAAA,GAAW,MAAM8C,oBAAa,CAAA;AAAA,MAClC,UAAY,EAAA,aAAA;AAAA,MACZ,SAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAI,IAAA,CAAC,mBAAoB,CAAA,QAAQ,CAAG,EAAA;AAClC,MAAA,MAAM,IAAIb,iBAAA;AAAA,QACR,CAAA,+CAAA,EACG,SAAoB,UACvB,CAAA;AAAA,OACF;AAAA;AAGF,IAAA,IAAI,CAAChC,aAAa,EAAA;AAChB,MAAO,OAAA,QAAA;AAAA;AAGT,IAAA,MAAM,CAAC,iBAAA,EAAmB,YAAY,CAAA,GACpC,MAAMA,aAAY,CAAA,oBAAA;AAAA,MAChB;AAAA,QACE,EAAE,YAAY8C,qCAAgC,EAAA;AAAA,QAC9C,EAAE,YAAYC,gCAA2B;AAAA,OAC3C;AAAA,MACA,EAAE,WAAY;AAAA,KAChB;AAGF,IAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,QAAS,CAAA,IAAA,CAAK,UAAU,CAAG,EAAA;AAC3C,MAAA,QAAA,CAAS,IAAK,CAAA,UAAA,GAAa,QAAS,CAAA,IAAA,CAAK,UAAW,CAAA,MAAA;AAAA,QAAO,CAAA,IAAA,KACzD,YAAa,CAAA,iBAAA,EAAmB,IAAI;AAAA,OACtC;AAAA,KACF,MAAA,IACE,QAAS,CAAA,IAAA,CAAK,UACd,IAAA,CAAC,aAAa,iBAAmB,EAAA,QAAA,CAAS,IAAK,CAAA,UAAU,CACzD,EAAA;AACA,MAAA,QAAA,CAAS,KAAK,UAAa,GAAA,KAAA,CAAA;AAAA;AAI7B,IAAA,QAAA,CAAS,IAAK,CAAA,KAAA,GAAQ,QAAS,CAAA,IAAA,CAAK,KAAM,CAAA,MAAA;AAAA,MAAO,CAAA,IAAA,KAC/C,YAAa,CAAA,YAAA,EAAc,IAAI;AAAA,KACjC;AAEA,IAAO,OAAA,QAAA;AAAA;AAGT,EAAO,OAAA,GAAA;AACT;;;;"}
|