@macedon-technologies/batman 1.33.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.jsii +248 -28
  2. package/API.md +212 -0
  3. package/README.md +26 -0
  4. package/factory/work-item-sources.md +24 -4
  5. package/lib/BatmanProject.d.ts +11 -0
  6. package/lib/BatmanProject.js +5 -2
  7. package/lib/BootcampProject.js +5 -2
  8. package/lib/CodeOwnersFile.js +1 -1
  9. package/lib/DataDogAspectFile.js +5 -18
  10. package/lib/PrAutoMergeWorkflow.js +1 -1
  11. package/lib/ProductionDeployWorkflow.js +1 -1
  12. package/lib/SecretConstructFile.js +4 -54
  13. package/lib/SecretHandlerFiles.js +6 -173
  14. package/lib/SoftwareFactoryBootstrap.d.ts +14 -3
  15. package/lib/SoftwareFactoryBootstrap.js +99 -15
  16. package/lib/SoftwareFactoryFiles.d.ts +13 -0
  17. package/lib/SoftwareFactoryFiles.js +22 -4
  18. package/lib/SoftwareFactoryJiraExtension.d.ts +14 -0
  19. package/lib/SoftwareFactoryJiraExtension.js +58 -0
  20. package/lib/SoftwareFactoryModels.d.ts +10 -0
  21. package/lib/SoftwareFactoryModels.js +26 -7
  22. package/lib/SoftwareFactoryWorkItemSources.d.ts +20 -3
  23. package/lib/SoftwareFactoryWorkItemSources.js +98 -9
  24. package/lib/StagingDeployWorkflow.js +1 -1
  25. package/lib/WorkItemSource.d.ts +67 -0
  26. package/lib/WorkItemSource.js +45 -0
  27. package/lib/index.d.ts +1 -0
  28. package/lib/index.js +1 -1
  29. package/lib/templates.d.ts +16 -0
  30. package/lib/templates.js +104 -0
  31. package/lib/utils.js +36 -3
  32. package/package.json +3 -2
  33. package/swamp-bootstrap/pull-extensions.ts +79 -10
  34. package/swamp-bootstrap/required-extensions.json +4 -0
  35. package/templates/app/swamp-bootstrap/pull-extensions.ts +79 -10
  36. package/templates/app/swamp-bootstrap/required-extensions.json +4 -0
  37. package/templates/jira/extensions/models/jira.ts +191 -0
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SecretConstructFile = void 0;
4
4
  const projen_1 = require("projen");
5
+ const templates_1 = require("./templates");
6
+ const SECRET_CONSTRUCT_PATH = 'src/constructs/Secret.ts';
5
7
  /**
6
8
  * Scaffolds src/constructs/Secret.ts: a Secrets Manager secret that keeps
7
9
  * manually changed values across deploys. Copied from @matthewbonig/secret (MIT),
@@ -9,60 +11,8 @@ const projen_1 = require("projen");
9
11
  */
10
12
  class SecretConstructFile extends projen_1.SampleFile {
11
13
  constructor(project) {
12
- super(project, 'src/constructs/Secret.ts', {
13
- contents: `// Copied from @matthewbonig/secret (MIT, https://github.com/mbonig/secret).
14
- // This file is generated by Batman and is yours to modify.
15
- import { join } from 'path';
16
- import { CustomResource } from 'aws-cdk-lib';
17
- import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';
18
- import { Runtime } from 'aws-cdk-lib/aws-lambda';
19
- import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
20
- import { Secret as AWSSecret, SecretProps, SecretStringGenerator } from 'aws-cdk-lib/aws-secretsmanager';
21
- import { Provider } from 'aws-cdk-lib/custom-resources';
22
- import { Construct } from 'constructs';
23
-
24
- export class Secret extends AWSSecret {
25
- constructor(scope: Construct, id: string, props: SecretProps) {
26
- super(scope, id, {
27
- ...props,
28
- generateSecretString: undefined, // explicitly set this to undefined so that we never use the built-in functionality
29
- });
30
-
31
- if (props.generateSecretString?.secretStringTemplate) {
32
- // now we're going to use a custom resource for this instead
33
- this.createCustomResource(props.generateSecretString);
34
- }
35
- }
36
-
37
- private createCustomResource(generateSecretString: SecretStringGenerator) {
38
- const eventHandler = new NodejsFunction(this, 'EventHandlerFunction', {
39
- runtime: Runtime.NODEJS_24_X,
40
- entry: join(__dirname, 'handler/Secret.Function.ts'),
41
- });
42
- this.grantWrite(eventHandler);
43
- this.grantRead(eventHandler);
44
- eventHandler.addToRolePolicy(new PolicyStatement({
45
- effect: Effect.ALLOW,
46
- resources: ['*'],
47
- actions: ['secretsmanager:GetRandomPassword'],
48
- }));
49
- const provider = new Provider(this, 'CustomResourceProvider', {
50
- onEventHandler: eventHandler,
51
- });
52
- const customResource = new CustomResource(this, 'GenerateSecretStringCR', {
53
- resourceType: 'Custom::GenerateSecretString',
54
- serviceToken: provider.serviceToken,
55
- properties: {
56
- Secret: this.secretArn,
57
- GenerateSecretString: generateSecretString,
58
- },
59
- });
60
- customResource.node.addDependency(this);
61
- }
62
- }
63
- `,
64
- });
14
+ super(project, SECRET_CONSTRUCT_PATH, (0, templates_1.templateFileOptions)(project, SECRET_CONSTRUCT_PATH));
65
15
  }
66
16
  }
67
17
  exports.SecretConstructFile = SecretConstructFile;
68
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VjcmV0Q29uc3RydWN0RmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9TZWNyZXRDb25zdHJ1Y3RGaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFvQztBQUdwQzs7OztHQUlHO0FBQ0gsTUFBYSxtQkFBb0IsU0FBUSxtQkFBVTtJQUNqRCxZQUFZLE9BQTRCO1FBQ3RDLEtBQUssQ0FBQyxPQUFPLEVBQUUsMEJBQTBCLEVBQUU7WUFDekMsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQWtEZjtTQUNJLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXhERCxrREF3REMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTYW1wbGVGaWxlIH0gZnJvbSAncHJvamVuJztcbmltcG9ydCB7IEF3c0Nka1R5cGVTY3JpcHRBcHAgfSBmcm9tICdwcm9qZW4vbGliL2F3c2Nkayc7XG5cbi8qKlxuICogU2NhZmZvbGRzIHNyYy9jb25zdHJ1Y3RzL1NlY3JldC50czogYSBTZWNyZXRzIE1hbmFnZXIgc2VjcmV0IHRoYXQga2VlcHNcbiAqIG1hbnVhbGx5IGNoYW5nZWQgdmFsdWVzIGFjcm9zcyBkZXBsb3lzLiBDb3BpZWQgZnJvbSBAbWF0dGhld2JvbmlnL3NlY3JldCAoTUlUKSxcbiAqIHdpdGggdGhlIGhhbmRsZXIgTGFtYmRhIG9uIE5vZGUuanMgMjQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWNyZXRDb25zdHJ1Y3RGaWxlIGV4dGVuZHMgU2FtcGxlRmlsZSB7XG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IEF3c0Nka1R5cGVTY3JpcHRBcHApIHtcbiAgICBzdXBlcihwcm9qZWN0LCAnc3JjL2NvbnN0cnVjdHMvU2VjcmV0LnRzJywge1xuICAgICAgY29udGVudHM6IGAvLyBDb3BpZWQgZnJvbSBAbWF0dGhld2JvbmlnL3NlY3JldCAoTUlULCBodHRwczovL2dpdGh1Yi5jb20vbWJvbmlnL3NlY3JldCkuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IEJhdG1hbiBhbmQgaXMgeW91cnMgdG8gbW9kaWZ5LlxuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBFZmZlY3QsIFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgUnVudGltZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgTm9kZWpzRnVuY3Rpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqcyc7XG5pbXBvcnQgeyBTZWNyZXQgYXMgQVdTU2VjcmV0LCBTZWNyZXRQcm9wcywgU2VjcmV0U3RyaW5nR2VuZXJhdG9yIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXNlY3JldHNtYW5hZ2VyJztcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuZXhwb3J0IGNsYXNzIFNlY3JldCBleHRlbmRzIEFXU1NlY3JldCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTZWNyZXRQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBnZW5lcmF0ZVNlY3JldFN0cmluZzogdW5kZWZpbmVkLCAvLyBleHBsaWNpdGx5IHNldCB0aGlzIHRvIHVuZGVmaW5lZCBzbyB0aGF0IHdlIG5ldmVyIHVzZSB0aGUgYnVpbHQtaW4gZnVuY3Rpb25hbGl0eVxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLmdlbmVyYXRlU2VjcmV0U3RyaW5nPy5zZWNyZXRTdHJpbmdUZW1wbGF0ZSkge1xuICAgICAgLy8gbm93IHdlJ3JlIGdvaW5nIHRvIHVzZSBhIGN1c3RvbSByZXNvdXJjZSBmb3IgdGhpcyBpbnN0ZWFkXG4gICAgICB0aGlzLmNyZWF0ZUN1c3RvbVJlc291cmNlKHByb3BzLmdlbmVyYXRlU2VjcmV0U3RyaW5nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUN1c3RvbVJlc291cmNlKGdlbmVyYXRlU2VjcmV0U3RyaW5nOiBTZWNyZXRTdHJpbmdHZW5lcmF0b3IpIHtcbiAgICBjb25zdCBldmVudEhhbmRsZXIgPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgJ0V2ZW50SGFuZGxlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjRfWCxcbiAgICAgIGVudHJ5OiBqb2luKF9fZGlybmFtZSwgJ2hhbmRsZXIvU2VjcmV0LkZ1bmN0aW9uLnRzJyksXG4gICAgfSk7XG4gICAgdGhpcy5ncmFudFdyaXRlKGV2ZW50SGFuZGxlcik7XG4gICAgdGhpcy5ncmFudFJlYWQoZXZlbnRIYW5kbGVyKTtcbiAgICBldmVudEhhbmRsZXIuYWRkVG9Sb2xlUG9saWN5KG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgYWN0aW9uczogWydzZWNyZXRzbWFuYWdlcjpHZXRSYW5kb21QYXNzd29yZCddLFxuICAgIH0pKTtcbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCAnQ3VzdG9tUmVzb3VyY2VQcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBldmVudEhhbmRsZXIsXG4gICAgfSk7XG4gICAgY29uc3QgY3VzdG9tUmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0dlbmVyYXRlU2VjcmV0U3RyaW5nQ1InLCB7XG4gICAgICByZXNvdXJjZVR5cGU6ICdDdXN0b206OkdlbmVyYXRlU2VjcmV0U3RyaW5nJyxcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBTZWNyZXQ6IHRoaXMuc2VjcmV0QXJuLFxuICAgICAgICBHZW5lcmF0ZVNlY3JldFN0cmluZzogZ2VuZXJhdGVTZWNyZXRTdHJpbmcsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGN1c3RvbVJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzKTtcbiAgfVxufVxuYCxcbiAgICB9KTtcbiAgfVxufVxuIl19
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VjcmV0Q29uc3RydWN0RmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9TZWNyZXRDb25zdHJ1Y3RGaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFvQztBQUVwQywyQ0FBa0Q7QUFFbEQsTUFBTSxxQkFBcUIsR0FBRywwQkFBMEIsQ0FBQztBQUV6RDs7OztHQUlHO0FBQ0gsTUFBYSxtQkFBb0IsU0FBUSxtQkFBVTtJQUNqRCxZQUFZLE9BQTRCO1FBQ3RDLEtBQUssQ0FBQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsSUFBQSwrQkFBbUIsRUFBQyxPQUFPLEVBQUUscUJBQXFCLENBQUMsQ0FBQyxDQUFDO0lBQzdGLENBQUM7Q0FDRjtBQUpELGtEQUlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2FtcGxlRmlsZSB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBBd3NDZGtUeXBlU2NyaXB0QXBwIH0gZnJvbSAncHJvamVuL2xpYi9hd3NjZGsnO1xuaW1wb3J0IHsgdGVtcGxhdGVGaWxlT3B0aW9ucyB9IGZyb20gJy4vdGVtcGxhdGVzJztcblxuY29uc3QgU0VDUkVUX0NPTlNUUlVDVF9QQVRIID0gJ3NyYy9jb25zdHJ1Y3RzL1NlY3JldC50cyc7XG5cbi8qKlxuICogU2NhZmZvbGRzIHNyYy9jb25zdHJ1Y3RzL1NlY3JldC50czogYSBTZWNyZXRzIE1hbmFnZXIgc2VjcmV0IHRoYXQga2VlcHNcbiAqIG1hbnVhbGx5IGNoYW5nZWQgdmFsdWVzIGFjcm9zcyBkZXBsb3lzLiBDb3BpZWQgZnJvbSBAbWF0dGhld2JvbmlnL3NlY3JldCAoTUlUKSxcbiAqIHdpdGggdGhlIGhhbmRsZXIgTGFtYmRhIG9uIE5vZGUuanMgMjQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWNyZXRDb25zdHJ1Y3RGaWxlIGV4dGVuZHMgU2FtcGxlRmlsZSB7XG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IEF3c0Nka1R5cGVTY3JpcHRBcHApIHtcbiAgICBzdXBlcihwcm9qZWN0LCBTRUNSRVRfQ09OU1RSVUNUX1BBVEgsIHRlbXBsYXRlRmlsZU9wdGlvbnMocHJvamVjdCwgU0VDUkVUX0NPTlNUUlVDVF9QQVRIKSk7XG4gIH1cbn1cbiJdfQ==
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SecretHandlerFiles = void 0;
4
4
  const projen_1 = require("projen");
5
+ const templates_1 = require("./templates");
6
+ const HANDLER_ENTRY_PATH = 'src/constructs/handler/Secret.Function.ts';
7
+ const HANDLER_DIR = 'src/constructs/handler/secret';
5
8
  /**
6
9
  * Scaffolds the Lambda handler sources used by the generated Secret construct
7
10
  * (src/constructs/Secret.ts). Copied from @matthewbonig/secret (MIT).
@@ -11,179 +14,9 @@ const projen_1 = require("projen");
11
14
  */
12
15
  class SecretHandlerFiles {
13
16
  constructor(project) {
14
- new projen_1.SampleFile(project, 'src/constructs/handler/Secret.Function.ts', {
15
- contents: `// Copied from @matthewbonig/secret (MIT, https://github.com/mbonig/secret).
16
- // This file is generated by Batman and is yours to modify.
17
- import { createSecretValue } from './secret/createSecretValue';
18
- import { updateSecretValue } from './secret/updateSecretValue';
19
-
20
- interface CustomResource {
21
- RequestType: 'Create' | 'Update' | 'Delete';
22
- LogicalResourceId: string;
23
- ResourceProperties: any;
24
- OldResourceProperties?: any;
25
- PhysicalResourceId?: string;
26
- }
27
-
28
- export const handler = async (event: CustomResource) => {
29
- console.log('Received event:', JSON.stringify(event, null, 2));
30
-
31
- switch (event.RequestType) {
32
- case 'Create':
33
- console.log(\`Create secret value for secret \${event.LogicalResourceId};\`);
34
- await createSecretValue({
35
- secretArn: event.ResourceProperties.Secret,
36
- generateSecretString: event.ResourceProperties.GenerateSecretString,
37
- });
38
- break;
39
- case 'Update':
40
- console.log('Updating secret with physical id:', event.PhysicalResourceId);
41
- await updateSecretValue({
42
- secretArn: event.ResourceProperties.Secret,
43
- generateSecretString: event.ResourceProperties.GenerateSecretString,
44
- oldGenerateSecretString: event.OldResourceProperties.GenerateSecretString,
45
- });
46
- break;
47
- case 'Delete':
48
- console.log('Deleting secret with physical id:', event.PhysicalResourceId);
49
- console.log('Doing nothing. deleting secrets requires no work at all.');
50
- break;
51
- }
52
- };
53
- `,
54
- });
55
- new projen_1.SampleFile(project, 'src/constructs/handler/secret/client.ts', {
56
- contents: `// Copied from @matthewbonig/secret (MIT, https://github.com/mbonig/secret).
57
- // This file is generated by Batman and is yours to modify.
58
- import { SecretsManager } from '@aws-sdk/client-secrets-manager';
59
-
60
- export const client = new SecretsManager({});
61
- `,
62
- });
63
- new projen_1.SampleFile(project, 'src/constructs/handler/secret/createSecretValue.ts', {
64
- contents: `// Copied from @matthewbonig/secret (MIT, https://github.com/mbonig/secret).
65
- // This file is generated by Batman and is yours to modify.
66
- import { GetRandomPasswordCommand, PutSecretValueCommand } from '@aws-sdk/client-secrets-manager';
67
- import { client } from './client';
68
-
69
- export async function createSecretValue({ generateSecretString, secretArn }: {
70
- secretArn: any;
71
- generateSecretString: any;
72
- }) {
73
- // since this is a create, we can just write the value as-is...
74
- const secretValue = JSON.parse(generateSecretString.secretStringTemplate);
75
- if (generateSecretString.generateStringKey) {
76
- const randomValue = await client.send(new GetRandomPasswordCommand({
77
- ExcludeCharacters: generateSecretString.excludeCharacters,
78
- ExcludeLowercase: generateSecretString.excludeLowercase,
79
- ExcludeNumbers: generateSecretString.excludeNumbers,
80
- ExcludePunctuation: generateSecretString.excludePunctuation,
81
- ExcludeUppercase: generateSecretString.excludeUppercase,
82
- IncludeSpace: generateSecretString.includeSpace,
83
- PasswordLength: generateSecretString.passwordLength,
84
- RequireEachIncludedType: generateSecretString.requireEachIncludedType,
85
- }));
86
- secretValue[generateSecretString.generateStringKey] = randomValue.RandomPassword;
87
- }
88
-
89
- await client.send(new PutSecretValueCommand({
90
- SecretId: secretArn,
91
- SecretString: JSON.stringify(secretValue),
92
- }));
93
- }
94
- `,
95
- });
96
- new projen_1.SampleFile(project, 'src/constructs/handler/secret/didRandomPropertiesChange.ts', {
97
- contents: `// Copied from @matthewbonig/secret (MIT, https://github.com/mbonig/secret).
98
- // This file is generated by Batman and is yours to modify.
99
- export function didRandomPropertiesChange(oldGenerateSecretString: any, generateSecretString: any) {
100
- return oldGenerateSecretString.excludeCharacters !== generateSecretString.excludeCharacters ||
101
- oldGenerateSecretString.excludeLowercase !== generateSecretString.excludeLowercase ||
102
- oldGenerateSecretString.excludeNumbers !== generateSecretString.excludeNumbers ||
103
- oldGenerateSecretString.excludePunctuation !== generateSecretString.excludePunctuation ||
104
- oldGenerateSecretString.excludeUppercase !== generateSecretString.excludeUppercase ||
105
- oldGenerateSecretString.includeSpace !== generateSecretString.includeSpace ||
106
- oldGenerateSecretString.passwordLength !== generateSecretString.passwordLength ||
107
- oldGenerateSecretString.requireEachIncludedType !== generateSecretString.requireEachIncludedType;
108
-
109
- }
110
- `,
111
- });
112
- new projen_1.SampleFile(project, 'src/constructs/handler/secret/updateSecretValue.ts', {
113
- contents: `// Copied from @matthewbonig/secret (MIT, https://github.com/mbonig/secret).
114
- // This file is generated by Batman and is yours to modify.
115
- import {
116
- GetRandomPasswordCommand,
117
- GetSecretValueCommand,
118
- PutSecretValueCommand,
119
- } from '@aws-sdk/client-secrets-manager';
120
- import { client } from './client';
121
- import { didRandomPropertiesChange } from './didRandomPropertiesChange';
122
-
123
- export async function updateSecretValue({ oldGenerateSecretString, generateSecretString, secretArn }: {
124
- secretArn: any;
125
- generateSecretString: any;
126
- oldGenerateSecretString: any;
127
- }) {
128
- // let's get the existing value
129
- const existingSecretValue = await client.send(new GetSecretValueCommand({
130
- SecretId: secretArn,
131
- }));
132
- // and parse the existing value
133
- let parsedValue: any = {};
134
-
135
- try {
136
- parsedValue = JSON.parse(existingSecretValue.SecretString!);
137
- } catch (err) {
138
- // the existing value couldn't be parsed, it was probably a random string.
139
- // let's go ahead and just start fresh then,
140
- }
141
-
142
- // now let's check what properties have changed
143
- const newSecretStringTemplate = JSON.parse(generateSecretString.secretStringTemplate);
144
- const oldSecretStringTemplate = JSON.parse(oldGenerateSecretString.secretStringTemplate);
145
- for (const key in newSecretStringTemplate) {
146
- if (oldSecretStringTemplate[key] === undefined) {
147
- // ok, so here's something to add...
148
- parsedValue[key] = newSecretStringTemplate[key];
149
- }
150
- if (oldSecretStringTemplate[key] !== newSecretStringTemplate[key]) {
151
- // ok, so here's something to update...
152
- parsedValue[key] = newSecretStringTemplate[key];
153
- }
154
- }
155
- for (const key in oldSecretStringTemplate) {
156
- if (newSecretStringTemplate[key] === undefined) {
157
- // ok, so here's something to remove...
158
- delete parsedValue[key];
159
- }
160
- }
161
-
162
- // did anything around the GenerateStringKey change?
163
- if (didRandomPropertiesChange(oldGenerateSecretString, generateSecretString)
164
- || generateSecretString.generateStringKey !== oldGenerateSecretString.generateStringKey) {
165
- const { RandomPassword: newRandomValue } = await client.send(new GetRandomPasswordCommand({
166
- ExcludeLowercase: generateSecretString.excludeLowercase === 'true',
167
- ExcludeNumbers: generateSecretString.excludeNumbers === 'true',
168
- ExcludePunctuation: generateSecretString.excludePunctuation === 'true',
169
- ExcludeUppercase: generateSecretString.excludeUppercase === 'true',
170
- IncludeSpace: generateSecretString.includeSpace === 'true',
171
- PasswordLength: +generateSecretString.passwordLength,
172
- RequireEachIncludedType: generateSecretString.requireEachIncludedType === 'true',
173
- }));
174
- parsedValue[generateSecretString.generateStringKey] = newRandomValue;
175
- }
176
-
177
- // update the secret in AWS
178
- await client.send(new PutSecretValueCommand({
179
- SecretId: secretArn,
180
- SecretString: JSON.stringify(parsedValue),
181
- }));
182
-
183
- }
184
- `,
185
- });
17
+ new projen_1.SampleFile(project, HANDLER_ENTRY_PATH, (0, templates_1.templateFileOptions)(project, HANDLER_ENTRY_PATH));
18
+ new projen_1.SampleDir(project, HANDLER_DIR, (0, templates_1.templateDirOptions)(project, HANDLER_DIR));
186
19
  }
187
20
  }
188
21
  exports.SecretHandlerFiles = SecretHandlerFiles;
189
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VjcmV0SGFuZGxlckZpbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NlY3JldEhhbmRsZXJGaWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBb0M7QUFHcEM7Ozs7OztHQU1HO0FBQ0gsTUFBYSxrQkFBa0I7SUFDN0IsWUFBWSxPQUE0QjtRQUN0QyxJQUFJLG1CQUFVLENBQUMsT0FBTyxFQUFFLDJDQUEyQyxFQUFFO1lBQ25FLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FzQ2Y7U0FDSSxDQUFDLENBQUM7UUFFSCxJQUFJLG1CQUFVLENBQUMsT0FBTyxFQUFFLHlDQUF5QyxFQUFFO1lBQ2pFLFFBQVEsRUFBRTs7Ozs7Q0FLZjtTQUNJLENBQUMsQ0FBQztRQUVILElBQUksbUJBQVUsQ0FBQyxPQUFPLEVBQUUsb0RBQW9ELEVBQUU7WUFDNUUsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0E4QmY7U0FDSSxDQUFDLENBQUM7UUFFSCxJQUFJLG1CQUFVLENBQUMsT0FBTyxFQUFFLDREQUE0RCxFQUFFO1lBQ3BGLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7OztDQWFmO1NBQ0ksQ0FBQyxDQUFDO1FBRUgsSUFBSSxtQkFBVSxDQUFDLE9BQU8sRUFBRSxvREFBb0QsRUFBRTtZQUM1RSxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBdUVmO1NBQ0ksQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBbkxELGdEQW1MQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNhbXBsZUZpbGUgfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgQXdzQ2RrVHlwZVNjcmlwdEFwcCB9IGZyb20gJ3Byb2plbi9saWIvYXdzY2RrJztcblxuLyoqXG4gKiBTY2FmZm9sZHMgdGhlIExhbWJkYSBoYW5kbGVyIHNvdXJjZXMgdXNlZCBieSB0aGUgZ2VuZXJhdGVkIFNlY3JldCBjb25zdHJ1Y3RcbiAqIChzcmMvY29uc3RydWN0cy9TZWNyZXQudHMpLiBDb3BpZWQgZnJvbSBAbWF0dGhld2JvbmlnL3NlY3JldCAoTUlUKS5cbiAqXG4gKiBUaGUgZW50cnkgZmlsZSBpcyBkZWxpYmVyYXRlbHkgbm90IG5hbWVkICoubGFtYmRhLnRzLCBzbyBwcm9qZW4ncyBsYW1iZGFcbiAqIGF1dG8tZGlzY292ZXJ5IGRvZXMgbm90IGdlbmVyYXRlIGEgc2Vjb25kIGZ1bmN0aW9uIGNsYXNzIGZvciBpdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlY3JldEhhbmRsZXJGaWxlcyB7XG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IEF3c0Nka1R5cGVTY3JpcHRBcHApIHtcbiAgICBuZXcgU2FtcGxlRmlsZShwcm9qZWN0LCAnc3JjL2NvbnN0cnVjdHMvaGFuZGxlci9TZWNyZXQuRnVuY3Rpb24udHMnLCB7XG4gICAgICBjb250ZW50czogYC8vIENvcGllZCBmcm9tIEBtYXR0aGV3Ym9uaWcvc2VjcmV0IChNSVQsIGh0dHBzOi8vZ2l0aHViLmNvbS9tYm9uaWcvc2VjcmV0KS5cbi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQgYnkgQmF0bWFuIGFuZCBpcyB5b3VycyB0byBtb2RpZnkuXG5pbXBvcnQgeyBjcmVhdGVTZWNyZXRWYWx1ZSB9IGZyb20gJy4vc2VjcmV0L2NyZWF0ZVNlY3JldFZhbHVlJztcbmltcG9ydCB7IHVwZGF0ZVNlY3JldFZhbHVlIH0gZnJvbSAnLi9zZWNyZXQvdXBkYXRlU2VjcmV0VmFsdWUnO1xuXG5pbnRlcmZhY2UgQ3VzdG9tUmVzb3VyY2Uge1xuICBSZXF1ZXN0VHlwZTogJ0NyZWF0ZScgfCAnVXBkYXRlJyB8ICdEZWxldGUnO1xuICBMb2dpY2FsUmVzb3VyY2VJZDogc3RyaW5nO1xuICBSZXNvdXJjZVByb3BlcnRpZXM6IGFueTtcbiAgT2xkUmVzb3VyY2VQcm9wZXJ0aWVzPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBoYW5kbGVyID0gYXN5bmMgKGV2ZW50OiBDdXN0b21SZXNvdXJjZSkgPT4ge1xuICBjb25zb2xlLmxvZygnUmVjZWl2ZWQgZXZlbnQ6JywgSlNPTi5zdHJpbmdpZnkoZXZlbnQsIG51bGwsIDIpKTtcblxuICBzd2l0Y2ggKGV2ZW50LlJlcXVlc3RUeXBlKSB7XG4gICAgY2FzZSAnQ3JlYXRlJzpcbiAgICAgIGNvbnNvbGUubG9nKFxcYENyZWF0ZSBzZWNyZXQgdmFsdWUgZm9yIHNlY3JldCBcXCR7ZXZlbnQuTG9naWNhbFJlc291cmNlSWR9O1xcYCk7XG4gICAgICBhd2FpdCBjcmVhdGVTZWNyZXRWYWx1ZSh7XG4gICAgICAgIHNlY3JldEFybjogZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLlNlY3JldCxcbiAgICAgICAgZ2VuZXJhdGVTZWNyZXRTdHJpbmc6IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5HZW5lcmF0ZVNlY3JldFN0cmluZyxcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnVXBkYXRlJzpcbiAgICAgIGNvbnNvbGUubG9nKCdVcGRhdGluZyBzZWNyZXQgd2l0aCBwaHlzaWNhbCBpZDonLCBldmVudC5QaHlzaWNhbFJlc291cmNlSWQpO1xuICAgICAgYXdhaXQgdXBkYXRlU2VjcmV0VmFsdWUoe1xuICAgICAgICBzZWNyZXRBcm46IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5TZWNyZXQsXG4gICAgICAgIGdlbmVyYXRlU2VjcmV0U3RyaW5nOiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuR2VuZXJhdGVTZWNyZXRTdHJpbmcsXG4gICAgICAgIG9sZEdlbmVyYXRlU2VjcmV0U3RyaW5nOiBldmVudC5PbGRSZXNvdXJjZVByb3BlcnRpZXMuR2VuZXJhdGVTZWNyZXRTdHJpbmcsXG4gICAgICB9KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0RlbGV0ZSc6XG4gICAgICBjb25zb2xlLmxvZygnRGVsZXRpbmcgc2VjcmV0IHdpdGggcGh5c2ljYWwgaWQ6JywgZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkKTtcbiAgICAgIGNvbnNvbGUubG9nKCdEb2luZyBub3RoaW5nLiBkZWxldGluZyBzZWNyZXRzIHJlcXVpcmVzIG5vIHdvcmsgYXQgYWxsLicpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5gLFxuICAgIH0pO1xuXG4gICAgbmV3IFNhbXBsZUZpbGUocHJvamVjdCwgJ3NyYy9jb25zdHJ1Y3RzL2hhbmRsZXIvc2VjcmV0L2NsaWVudC50cycsIHtcbiAgICAgIGNvbnRlbnRzOiBgLy8gQ29waWVkIGZyb20gQG1hdHRoZXdib25pZy9zZWNyZXQgKE1JVCwgaHR0cHM6Ly9naXRodWIuY29tL21ib25pZy9zZWNyZXQpLlxuLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZCBieSBCYXRtYW4gYW5kIGlzIHlvdXJzIHRvIG1vZGlmeS5cbmltcG9ydCB7IFNlY3JldHNNYW5hZ2VyIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNlY3JldHMtbWFuYWdlcic7XG5cbmV4cG9ydCBjb25zdCBjbGllbnQgPSBuZXcgU2VjcmV0c01hbmFnZXIoe30pO1xuYCxcbiAgICB9KTtcblxuICAgIG5ldyBTYW1wbGVGaWxlKHByb2plY3QsICdzcmMvY29uc3RydWN0cy9oYW5kbGVyL3NlY3JldC9jcmVhdGVTZWNyZXRWYWx1ZS50cycsIHtcbiAgICAgIGNvbnRlbnRzOiBgLy8gQ29waWVkIGZyb20gQG1hdHRoZXdib25pZy9zZWNyZXQgKE1JVCwgaHR0cHM6Ly9naXRodWIuY29tL21ib25pZy9zZWNyZXQpLlxuLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZCBieSBCYXRtYW4gYW5kIGlzIHlvdXJzIHRvIG1vZGlmeS5cbmltcG9ydCB7IEdldFJhbmRvbVBhc3N3b3JkQ29tbWFuZCwgUHV0U2VjcmV0VmFsdWVDb21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNlY3JldHMtbWFuYWdlcic7XG5pbXBvcnQgeyBjbGllbnQgfSBmcm9tICcuL2NsaWVudCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVTZWNyZXRWYWx1ZSh7IGdlbmVyYXRlU2VjcmV0U3RyaW5nLCBzZWNyZXRBcm4gfToge1xuICBzZWNyZXRBcm46IGFueTtcbiAgZ2VuZXJhdGVTZWNyZXRTdHJpbmc6IGFueTtcbn0pIHtcbiAgLy8gc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSwgd2UgY2FuIGp1c3Qgd3JpdGUgdGhlIHZhbHVlIGFzLWlzLi4uXG4gIGNvbnN0IHNlY3JldFZhbHVlID0gSlNPTi5wYXJzZShnZW5lcmF0ZVNlY3JldFN0cmluZy5zZWNyZXRTdHJpbmdUZW1wbGF0ZSk7XG4gIGlmIChnZW5lcmF0ZVNlY3JldFN0cmluZy5nZW5lcmF0ZVN0cmluZ0tleSkge1xuICAgIGNvbnN0IHJhbmRvbVZhbHVlID0gYXdhaXQgY2xpZW50LnNlbmQobmV3IEdldFJhbmRvbVBhc3N3b3JkQ29tbWFuZCh7XG4gICAgICBFeGNsdWRlQ2hhcmFjdGVyczogZ2VuZXJhdGVTZWNyZXRTdHJpbmcuZXhjbHVkZUNoYXJhY3RlcnMsXG4gICAgICBFeGNsdWRlTG93ZXJjYXNlOiBnZW5lcmF0ZVNlY3JldFN0cmluZy5leGNsdWRlTG93ZXJjYXNlLFxuICAgICAgRXhjbHVkZU51bWJlcnM6IGdlbmVyYXRlU2VjcmV0U3RyaW5nLmV4Y2x1ZGVOdW1iZXJzLFxuICAgICAgRXhjbHVkZVB1bmN0dWF0aW9uOiBnZW5lcmF0ZVNlY3JldFN0cmluZy5leGNsdWRlUHVuY3R1YXRpb24sXG4gICAgICBFeGNsdWRlVXBwZXJjYXNlOiBnZW5lcmF0ZVNlY3JldFN0cmluZy5leGNsdWRlVXBwZXJjYXNlLFxuICAgICAgSW5jbHVkZVNwYWNlOiBnZW5lcmF0ZVNlY3JldFN0cmluZy5pbmNsdWRlU3BhY2UsXG4gICAgICBQYXNzd29yZExlbmd0aDogZ2VuZXJhdGVTZWNyZXRTdHJpbmcucGFzc3dvcmRMZW5ndGgsXG4gICAgICBSZXF1aXJlRWFjaEluY2x1ZGVkVHlwZTogZ2VuZXJhdGVTZWNyZXRTdHJpbmcucmVxdWlyZUVhY2hJbmNsdWRlZFR5cGUsXG4gICAgfSkpO1xuICAgIHNlY3JldFZhbHVlW2dlbmVyYXRlU2VjcmV0U3RyaW5nLmdlbmVyYXRlU3RyaW5nS2V5XSA9IHJhbmRvbVZhbHVlLlJhbmRvbVBhc3N3b3JkO1xuICB9XG5cbiAgYXdhaXQgY2xpZW50LnNlbmQobmV3IFB1dFNlY3JldFZhbHVlQ29tbWFuZCh7XG4gICAgU2VjcmV0SWQ6IHNlY3JldEFybixcbiAgICBTZWNyZXRTdHJpbmc6IEpTT04uc3RyaW5naWZ5KHNlY3JldFZhbHVlKSxcbiAgfSkpO1xufVxuYCxcbiAgICB9KTtcblxuICAgIG5ldyBTYW1wbGVGaWxlKHByb2plY3QsICdzcmMvY29uc3RydWN0cy9oYW5kbGVyL3NlY3JldC9kaWRSYW5kb21Qcm9wZXJ0aWVzQ2hhbmdlLnRzJywge1xuICAgICAgY29udGVudHM6IGAvLyBDb3BpZWQgZnJvbSBAbWF0dGhld2JvbmlnL3NlY3JldCAoTUlULCBodHRwczovL2dpdGh1Yi5jb20vbWJvbmlnL3NlY3JldCkuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IEJhdG1hbiBhbmQgaXMgeW91cnMgdG8gbW9kaWZ5LlxuZXhwb3J0IGZ1bmN0aW9uIGRpZFJhbmRvbVByb3BlcnRpZXNDaGFuZ2Uob2xkR2VuZXJhdGVTZWNyZXRTdHJpbmc6IGFueSwgZ2VuZXJhdGVTZWNyZXRTdHJpbmc6IGFueSkge1xuICByZXR1cm4gb2xkR2VuZXJhdGVTZWNyZXRTdHJpbmcuZXhjbHVkZUNoYXJhY3RlcnMgIT09IGdlbmVyYXRlU2VjcmV0U3RyaW5nLmV4Y2x1ZGVDaGFyYWN0ZXJzIHx8XG4gICAgb2xkR2VuZXJhdGVTZWNyZXRTdHJpbmcuZXhjbHVkZUxvd2VyY2FzZSAhPT0gZ2VuZXJhdGVTZWNyZXRTdHJpbmcuZXhjbHVkZUxvd2VyY2FzZSB8fFxuICAgIG9sZEdlbmVyYXRlU2VjcmV0U3RyaW5nLmV4Y2x1ZGVOdW1iZXJzICE9PSBnZW5lcmF0ZVNlY3JldFN0cmluZy5leGNsdWRlTnVtYmVycyB8fFxuICAgIG9sZEdlbmVyYXRlU2VjcmV0U3RyaW5nLmV4Y2x1ZGVQdW5jdHVhdGlvbiAhPT0gZ2VuZXJhdGVTZWNyZXRTdHJpbmcuZXhjbHVkZVB1bmN0dWF0aW9uIHx8XG4gICAgb2xkR2VuZXJhdGVTZWNyZXRTdHJpbmcuZXhjbHVkZVVwcGVyY2FzZSAhPT0gZ2VuZXJhdGVTZWNyZXRTdHJpbmcuZXhjbHVkZVVwcGVyY2FzZSB8fFxuICAgIG9sZEdlbmVyYXRlU2VjcmV0U3RyaW5nLmluY2x1ZGVTcGFjZSAhPT0gZ2VuZXJhdGVTZWNyZXRTdHJpbmcuaW5jbHVkZVNwYWNlIHx8XG4gICAgb2xkR2VuZXJhdGVTZWNyZXRTdHJpbmcucGFzc3dvcmRMZW5ndGggIT09IGdlbmVyYXRlU2VjcmV0U3RyaW5nLnBhc3N3b3JkTGVuZ3RoIHx8XG4gICAgb2xkR2VuZXJhdGVTZWNyZXRTdHJpbmcucmVxdWlyZUVhY2hJbmNsdWRlZFR5cGUgIT09IGdlbmVyYXRlU2VjcmV0U3RyaW5nLnJlcXVpcmVFYWNoSW5jbHVkZWRUeXBlO1xuXG59XG5gLFxuICAgIH0pO1xuXG4gICAgbmV3IFNhbXBsZUZpbGUocHJvamVjdCwgJ3NyYy9jb25zdHJ1Y3RzL2hhbmRsZXIvc2VjcmV0L3VwZGF0ZVNlY3JldFZhbHVlLnRzJywge1xuICAgICAgY29udGVudHM6IGAvLyBDb3BpZWQgZnJvbSBAbWF0dGhld2JvbmlnL3NlY3JldCAoTUlULCBodHRwczovL2dpdGh1Yi5jb20vbWJvbmlnL3NlY3JldCkuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IEJhdG1hbiBhbmQgaXMgeW91cnMgdG8gbW9kaWZ5LlxuaW1wb3J0IHtcbiAgR2V0UmFuZG9tUGFzc3dvcmRDb21tYW5kLFxuICBHZXRTZWNyZXRWYWx1ZUNvbW1hbmQsXG4gIFB1dFNlY3JldFZhbHVlQ29tbWFuZCxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNlY3JldHMtbWFuYWdlcic7XG5pbXBvcnQgeyBjbGllbnQgfSBmcm9tICcuL2NsaWVudCc7XG5pbXBvcnQgeyBkaWRSYW5kb21Qcm9wZXJ0aWVzQ2hhbmdlIH0gZnJvbSAnLi9kaWRSYW5kb21Qcm9wZXJ0aWVzQ2hhbmdlJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVNlY3JldFZhbHVlKHsgb2xkR2VuZXJhdGVTZWNyZXRTdHJpbmcsIGdlbmVyYXRlU2VjcmV0U3RyaW5nLCBzZWNyZXRBcm4gfToge1xuICBzZWNyZXRBcm46IGFueTtcbiAgZ2VuZXJhdGVTZWNyZXRTdHJpbmc6IGFueTtcbiAgb2xkR2VuZXJhdGVTZWNyZXRTdHJpbmc6IGFueTtcbn0pIHtcbiAgLy8gbGV0J3MgZ2V0IHRoZSBleGlzdGluZyB2YWx1ZVxuICBjb25zdCBleGlzdGluZ1NlY3JldFZhbHVlID0gYXdhaXQgY2xpZW50LnNlbmQobmV3IEdldFNlY3JldFZhbHVlQ29tbWFuZCh7XG4gICAgU2VjcmV0SWQ6IHNlY3JldEFybixcbiAgfSkpO1xuICAvLyBhbmQgcGFyc2UgdGhlIGV4aXN0aW5nIHZhbHVlXG4gIGxldCBwYXJzZWRWYWx1ZTogYW55ID0ge307XG5cbiAgdHJ5IHtcbiAgICBwYXJzZWRWYWx1ZSA9IEpTT04ucGFyc2UoZXhpc3RpbmdTZWNyZXRWYWx1ZS5TZWNyZXRTdHJpbmchKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gdGhlIGV4aXN0aW5nIHZhbHVlIGNvdWxkbid0IGJlIHBhcnNlZCwgaXQgd2FzIHByb2JhYmx5IGEgcmFuZG9tIHN0cmluZy5cbiAgICAvLyBsZXQncyBnbyBhaGVhZCBhbmQganVzdCBzdGFydCBmcmVzaCB0aGVuLFxuICB9XG5cbiAgLy8gbm93IGxldCdzIGNoZWNrIHdoYXQgcHJvcGVydGllcyBoYXZlIGNoYW5nZWRcbiAgY29uc3QgbmV3U2VjcmV0U3RyaW5nVGVtcGxhdGUgPSBKU09OLnBhcnNlKGdlbmVyYXRlU2VjcmV0U3RyaW5nLnNlY3JldFN0cmluZ1RlbXBsYXRlKTtcbiAgY29uc3Qgb2xkU2VjcmV0U3RyaW5nVGVtcGxhdGUgPSBKU09OLnBhcnNlKG9sZEdlbmVyYXRlU2VjcmV0U3RyaW5nLnNlY3JldFN0cmluZ1RlbXBsYXRlKTtcbiAgZm9yIChjb25zdCBrZXkgaW4gbmV3U2VjcmV0U3RyaW5nVGVtcGxhdGUpIHtcbiAgICBpZiAob2xkU2VjcmV0U3RyaW5nVGVtcGxhdGVba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBvaywgc28gaGVyZSdzIHNvbWV0aGluZyB0byBhZGQuLi5cbiAgICAgIHBhcnNlZFZhbHVlW2tleV0gPSBuZXdTZWNyZXRTdHJpbmdUZW1wbGF0ZVtrZXldO1xuICAgIH1cbiAgICBpZiAob2xkU2VjcmV0U3RyaW5nVGVtcGxhdGVba2V5XSAhPT0gbmV3U2VjcmV0U3RyaW5nVGVtcGxhdGVba2V5XSkge1xuICAgICAgLy8gb2ssIHNvIGhlcmUncyBzb21ldGhpbmcgdG8gdXBkYXRlLi4uXG4gICAgICBwYXJzZWRWYWx1ZVtrZXldID0gbmV3U2VjcmV0U3RyaW5nVGVtcGxhdGVba2V5XTtcbiAgICB9XG4gIH1cbiAgZm9yIChjb25zdCBrZXkgaW4gb2xkU2VjcmV0U3RyaW5nVGVtcGxhdGUpIHtcbiAgICBpZiAobmV3U2VjcmV0U3RyaW5nVGVtcGxhdGVba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBvaywgc28gaGVyZSdzIHNvbWV0aGluZyB0byByZW1vdmUuLi5cbiAgICAgIGRlbGV0ZSBwYXJzZWRWYWx1ZVtrZXldO1xuICAgIH1cbiAgfVxuXG4gIC8vIGRpZCBhbnl0aGluZyBhcm91bmQgdGhlIEdlbmVyYXRlU3RyaW5nS2V5IGNoYW5nZT9cbiAgaWYgKGRpZFJhbmRvbVByb3BlcnRpZXNDaGFuZ2Uob2xkR2VuZXJhdGVTZWNyZXRTdHJpbmcsIGdlbmVyYXRlU2VjcmV0U3RyaW5nKVxuICAgIHx8IGdlbmVyYXRlU2VjcmV0U3RyaW5nLmdlbmVyYXRlU3RyaW5nS2V5ICE9PSBvbGRHZW5lcmF0ZVNlY3JldFN0cmluZy5nZW5lcmF0ZVN0cmluZ0tleSkge1xuICAgIGNvbnN0IHsgUmFuZG9tUGFzc3dvcmQ6IG5ld1JhbmRvbVZhbHVlIH0gPSBhd2FpdCBjbGllbnQuc2VuZChuZXcgR2V0UmFuZG9tUGFzc3dvcmRDb21tYW5kKHtcbiAgICAgIEV4Y2x1ZGVMb3dlcmNhc2U6IGdlbmVyYXRlU2VjcmV0U3RyaW5nLmV4Y2x1ZGVMb3dlcmNhc2UgPT09ICd0cnVlJyxcbiAgICAgIEV4Y2x1ZGVOdW1iZXJzOiBnZW5lcmF0ZVNlY3JldFN0cmluZy5leGNsdWRlTnVtYmVycyA9PT0gJ3RydWUnLFxuICAgICAgRXhjbHVkZVB1bmN0dWF0aW9uOiBnZW5lcmF0ZVNlY3JldFN0cmluZy5leGNsdWRlUHVuY3R1YXRpb24gPT09ICd0cnVlJyxcbiAgICAgIEV4Y2x1ZGVVcHBlcmNhc2U6IGdlbmVyYXRlU2VjcmV0U3RyaW5nLmV4Y2x1ZGVVcHBlcmNhc2UgPT09ICd0cnVlJyxcbiAgICAgIEluY2x1ZGVTcGFjZTogZ2VuZXJhdGVTZWNyZXRTdHJpbmcuaW5jbHVkZVNwYWNlID09PSAndHJ1ZScsXG4gICAgICBQYXNzd29yZExlbmd0aDogK2dlbmVyYXRlU2VjcmV0U3RyaW5nLnBhc3N3b3JkTGVuZ3RoLFxuICAgICAgUmVxdWlyZUVhY2hJbmNsdWRlZFR5cGU6IGdlbmVyYXRlU2VjcmV0U3RyaW5nLnJlcXVpcmVFYWNoSW5jbHVkZWRUeXBlID09PSAndHJ1ZScsXG4gICAgfSkpO1xuICAgIHBhcnNlZFZhbHVlW2dlbmVyYXRlU2VjcmV0U3RyaW5nLmdlbmVyYXRlU3RyaW5nS2V5XSA9IG5ld1JhbmRvbVZhbHVlO1xuICB9XG5cbiAgLy8gdXBkYXRlIHRoZSBzZWNyZXQgaW4gQVdTXG4gIGF3YWl0IGNsaWVudC5zZW5kKG5ldyBQdXRTZWNyZXRWYWx1ZUNvbW1hbmQoe1xuICAgIFNlY3JldElkOiBzZWNyZXRBcm4sXG4gICAgU2VjcmV0U3RyaW5nOiBKU09OLnN0cmluZ2lmeShwYXJzZWRWYWx1ZSksXG4gIH0pKTtcblxufVxuYCxcbiAgICB9KTtcbiAgfVxufVxuIl19
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VjcmV0SGFuZGxlckZpbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NlY3JldEhhbmRsZXJGaWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBK0M7QUFFL0MsMkNBQXNFO0FBRXRFLE1BQU0sa0JBQWtCLEdBQUcsMkNBQTJDLENBQUM7QUFDdkUsTUFBTSxXQUFXLEdBQUcsK0JBQStCLENBQUM7QUFFcEQ7Ozs7OztHQU1HO0FBQ0gsTUFBYSxrQkFBa0I7SUFDN0IsWUFBWSxPQUE0QjtRQUN0QyxJQUFJLG1CQUFVLENBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLElBQUEsK0JBQW1CLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQztRQUM5RixJQUFJLGtCQUFTLENBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxJQUFBLDhCQUFrQixFQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQ2hGLENBQUM7Q0FDRjtBQUxELGdEQUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2FtcGxlRGlyLCBTYW1wbGVGaWxlIH0gZnJvbSAncHJvamVuJztcbmltcG9ydCB7IEF3c0Nka1R5cGVTY3JpcHRBcHAgfSBmcm9tICdwcm9qZW4vbGliL2F3c2Nkayc7XG5pbXBvcnQgeyB0ZW1wbGF0ZURpck9wdGlvbnMsIHRlbXBsYXRlRmlsZU9wdGlvbnMgfSBmcm9tICcuL3RlbXBsYXRlcyc7XG5cbmNvbnN0IEhBTkRMRVJfRU5UUllfUEFUSCA9ICdzcmMvY29uc3RydWN0cy9oYW5kbGVyL1NlY3JldC5GdW5jdGlvbi50cyc7XG5jb25zdCBIQU5ETEVSX0RJUiA9ICdzcmMvY29uc3RydWN0cy9oYW5kbGVyL3NlY3JldCc7XG5cbi8qKlxuICogU2NhZmZvbGRzIHRoZSBMYW1iZGEgaGFuZGxlciBzb3VyY2VzIHVzZWQgYnkgdGhlIGdlbmVyYXRlZCBTZWNyZXQgY29uc3RydWN0XG4gKiAoc3JjL2NvbnN0cnVjdHMvU2VjcmV0LnRzKS4gQ29waWVkIGZyb20gQG1hdHRoZXdib25pZy9zZWNyZXQgKE1JVCkuXG4gKlxuICogVGhlIGVudHJ5IGZpbGUgaXMgZGVsaWJlcmF0ZWx5IG5vdCBuYW1lZCAqLmxhbWJkYS50cywgc28gcHJvamVuJ3MgbGFtYmRhXG4gKiBhdXRvLWRpc2NvdmVyeSBkb2VzIG5vdCBnZW5lcmF0ZSBhIHNlY29uZCBmdW5jdGlvbiBjbGFzcyBmb3IgaXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWNyZXRIYW5kbGVyRmlsZXMge1xuICBjb25zdHJ1Y3Rvcihwcm9qZWN0OiBBd3NDZGtUeXBlU2NyaXB0QXBwKSB7XG4gICAgbmV3IFNhbXBsZUZpbGUocHJvamVjdCwgSEFORExFUl9FTlRSWV9QQVRILCB0ZW1wbGF0ZUZpbGVPcHRpb25zKHByb2plY3QsIEhBTkRMRVJfRU5UUllfUEFUSCkpO1xuICAgIG5ldyBTYW1wbGVEaXIocHJvamVjdCwgSEFORExFUl9ESVIsIHRlbXBsYXRlRGlyT3B0aW9ucyhwcm9qZWN0LCBIQU5ETEVSX0RJUikpO1xuICB9XG59XG4iXX0=
@@ -1,10 +1,21 @@
1
1
  import { NodeProject } from 'projen/lib/javascript';
2
+ import { WorkItemSource } from './WorkItemSource';
3
+ export declare const REQUIRED_EXTENSIONS_PATH = "swamp-bootstrap/required-extensions.json";
4
+ export interface SoftwareFactoryBootstrapOptions {
5
+ /**
6
+ * The enabled work-item sources, whose extensions bootstrap keeps at or
7
+ * above their minimum versions.
8
+ */
9
+ readonly workItemSources: WorkItemSource[];
10
+ }
2
11
  /**
3
12
  * The extension step of `swamp:bootstrap`: a Node script, so it runs the same
4
13
  * under projen's PowerShell 5.1 task shell on Windows as under bash/sh, that
5
- * pulls every extension at the version pinned in the repo's swamp lockfile.
6
- * Fully generic — no per-repo parameterization.
14
+ * pulls every extension at the version pinned in the repo's swamp lockfile,
15
+ * then raises any extension below the minimum the enabled work-item sources
16
+ * need. The script is the same for every project; the minimums come from the
17
+ * generated `required-extensions.json`.
7
18
  */
8
19
  export declare class SoftwareFactoryBootstrap {
9
- constructor(project: NodeProject);
20
+ constructor(project: NodeProject, options: SoftwareFactoryBootstrapOptions);
10
21
  }
@@ -1,15 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoftwareFactoryBootstrap = void 0;
3
+ exports.SoftwareFactoryBootstrap = exports.REQUIRED_EXTENSIONS_PATH = void 0;
4
4
  const projen_1 = require("projen");
5
+ const WorkItemSource_1 = require("./WorkItemSource");
6
+ exports.REQUIRED_EXTENSIONS_PATH = 'swamp-bootstrap/required-extensions.json';
7
+ const SOURCE_EXTENSIONS = {
8
+ [WorkItemSource_1.WorkItemSource.GITHUB]: ['@webframp/github', '2026.09.08.1'],
9
+ };
5
10
  /**
6
11
  * The extension step of `swamp:bootstrap`: a Node script, so it runs the same
7
12
  * under projen's PowerShell 5.1 task shell on Windows as under bash/sh, that
8
- * pulls every extension at the version pinned in the repo's swamp lockfile.
9
- * Fully generic — no per-repo parameterization.
13
+ * pulls every extension at the version pinned in the repo's swamp lockfile,
14
+ * then raises any extension below the minimum the enabled work-item sources
15
+ * need. The script is the same for every project; the minimums come from the
16
+ * generated `required-extensions.json`.
10
17
  */
11
18
  class SoftwareFactoryBootstrap {
12
- constructor(project) {
19
+ constructor(project, options) {
20
+ new projen_1.JsonFile(project, exports.REQUIRED_EXTENSIONS_PATH, {
21
+ marker: true,
22
+ readonly: true,
23
+ obj: Object.fromEntries(options.workItemSources.flatMap((source) => {
24
+ const extension = SOURCE_EXTENSIONS[source];
25
+ return extension ? [extension] : [];
26
+ })),
27
+ });
13
28
  new projen_1.TextFile(project, 'swamp-bootstrap/pull-extensions.ts', {
14
29
  marker: true,
15
30
  lines: [
@@ -24,11 +39,18 @@ class SoftwareFactoryBootstrap {
24
39
  ' * it writes backslash paths and deletes the committed files it tracks (e.g.',
25
40
  ' * .claude/skills/software-factory/). So afterwards the lockfile and every',
26
41
  ' * git-tracked file it lists are restored from git.',
42
+ ' *',
43
+ ' * Then each extension in swamp-bootstrap/required-extensions.json that the',
44
+ ' * lockfile lacks, or pins below the listed minimum, is pulled at that',
45
+ ' * minimum. The tracked files it lists are restored again, except the',
46
+ ' * lockfile, whose paths are normalized to forward slashes so it is the only',
47
+ ' * change left to commit.',
27
48
  ' */',
28
49
  "import { execFileSync } from 'node:child_process';",
29
- "import { existsSync, readFileSync } from 'node:fs';",
50
+ "import { existsSync, readFileSync, writeFileSync } from 'node:fs';",
30
51
  '',
31
52
  "const LOCKFILE = 'extensions/models/upstream_extensions.json';",
53
+ "const REQUIRED_EXTENSIONS = 'swamp-bootstrap/required-extensions.json';",
32
54
  "const DEFAULT_EXTENSIONS = ['@swamp/software-factory', '@webframp/github', '@goodcraft/github'];",
33
55
  '',
34
56
  'interface LockfileEntry {',
@@ -52,12 +74,45 @@ class SoftwareFactoryBootstrap {
52
74
  " execFileSync('swamp', ['extension', 'pull', extension, '--force'], { stdio: 'inherit' });",
53
75
  '}',
54
76
  '',
55
- 'function restoreTrackedFiles(lockfile: Record<string, LockfileEntry>): void {',
77
+ 'function readRequiredExtensions(): Record<string, string> {',
78
+ ' if (!existsSync(REQUIRED_EXTENSIONS)) {',
79
+ ' return {};',
80
+ ' }',
81
+ " const required = JSON.parse(readFileSync(REQUIRED_EXTENSIONS, 'utf8')) as Record<string, string>;",
82
+ " return Object.fromEntries(Object.entries(required).filter(([name]) => name.startsWith('@')));",
83
+ '}',
84
+ '',
85
+ 'function isOlder(version: string | undefined, minimum: string): boolean {',
86
+ ' for (const value of [version, minimum]) {',
87
+ " if (typeof value !== 'string' || !/^\\d+(\\.\\d+)*$/.test(value)) {",
88
+ ' throw new Error(`Cannot compare extension version ${JSON.stringify(value)}: expected digits separated by dots`);',
89
+ ' }',
90
+ ' }',
91
+ " const have = version!.split('.').map(Number);",
92
+ " const want = minimum.split('.').map(Number);",
93
+ ' for (let i = 0; i < Math.max(have.length, want.length); i++) {',
94
+ ' const difference = (have[i] ?? 0) - (want[i] ?? 0);',
95
+ ' if (difference !== 0) {',
96
+ ' return difference < 0;',
97
+ ' }',
98
+ ' }',
99
+ ' return false;',
100
+ '}',
101
+ '',
102
+ 'function toPosix(file: string): string {',
103
+ " return file.replace(/\\\\/g, '/');",
104
+ '}',
105
+ '',
106
+ 'function restoreTrackedFiles(lockfile: Record<string, LockfileEntry>, includeLockfile = true): void {',
56
107
  ' const listed = Object.values(lockfile)',
57
108
  ' .flatMap((entry) => entry.files ?? [])',
58
- " .map((file) => file.replace(/\\\\/g, '/'))",
109
+ ' .map(toPosix)',
59
110
  " .filter((file) => !file.startsWith('.swamp/'));",
60
- " const tracked = run('git', ['ls-files', '-z', '--', LOCKFILE, ...listed])",
111
+ ' const paths = [...(includeLockfile ? [LOCKFILE] : []), ...listed];',
112
+ ' if (paths.length === 0) {',
113
+ ' return;',
114
+ ' }',
115
+ " const tracked = run('git', ['ls-files', '-z', '--', ...paths])",
61
116
  " .split('\\0')",
62
117
  ' .filter(Boolean);',
63
118
  ' if (tracked.length > 0) {',
@@ -66,18 +121,47 @@ class SoftwareFactoryBootstrap {
66
121
  ' }',
67
122
  '}',
68
123
  '',
124
+ 'function normalizeLockfile(lockfile: Record<string, LockfileEntry>): void {',
125
+ ' for (const entry of Object.values(lockfile)) {',
126
+ ' if (entry.files) {',
127
+ ' entry.files = entry.files.map(toPosix);',
128
+ ' }',
129
+ ' }',
130
+ ' writeFileSync(LOCKFILE, `${JSON.stringify(lockfile, null, 2)}\\n`);',
131
+ '}',
132
+ '',
133
+ 'function pullRequiredExtensions(): void {',
134
+ ' const lockfile = readLockfile() ?? {};',
135
+ ' const needed = Object.entries(readRequiredExtensions())',
136
+ ' .filter(([name, minimum]) => !lockfile[name] || isOlder(lockfile[name].version, minimum));',
137
+ ' if (needed.length === 0) {',
138
+ ' return;',
139
+ ' }',
140
+ ' for (const [name, minimum] of needed) {',
141
+ ' pull(`${name}@${minimum}`);',
142
+ ' }',
143
+ ' const updated = readLockfile();',
144
+ ' if (updated) {',
145
+ ' const pulled = new Set(needed.map(([name]) => name));',
146
+ ' restoreTrackedFiles(Object.fromEntries(Object.entries(updated).filter(([name]) => !pulled.has(name))), false);',
147
+ ' normalizeLockfile(updated);',
148
+ ' }',
149
+ " const pinned = needed.map(([name, minimum]) => `${name}@${minimum}`).join(', ');",
150
+ ' console.log(`Commit ${LOCKFILE}: it now pins ${pinned}`);',
151
+ '}',
152
+ '',
69
153
  'function main(): void {',
70
154
  ' const lockfile = readLockfile();',
71
155
  ' if (!lockfile) {',
72
156
  ' console.log(`No ${LOCKFILE} yet: pulling the latest stable software-factory extensions`);',
73
157
  ' DEFAULT_EXTENSIONS.forEach(pull);',
74
- ' return;',
75
- ' }',
76
- '',
77
- ' for (const [name, entry] of Object.entries(lockfile)) {',
78
- ' pull(`${name}@${entry.version}`);',
158
+ ' } else {',
159
+ ' for (const [name, entry] of Object.entries(lockfile)) {',
160
+ ' pull(`${name}@${entry.version}`);',
161
+ ' }',
162
+ ' restoreTrackedFiles(lockfile);',
79
163
  ' }',
80
- ' restoreTrackedFiles(lockfile);',
164
+ ' pullRequiredExtensions();',
81
165
  '}',
82
166
  '',
83
167
  'main();',
@@ -98,4 +182,4 @@ class SoftwareFactoryBootstrap {
98
182
  }
99
183
  }
100
184
  exports.SoftwareFactoryBootstrap = SoftwareFactoryBootstrap;
101
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU29mdHdhcmVGYWN0b3J5Qm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NvZnR3YXJlRmFjdG9yeUJvb3RzdHJhcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBNEM7QUFHNUM7Ozs7O0dBS0c7QUFDSCxNQUFhLHdCQUF3QjtJQUNuQyxZQUFZLE9BQW9CO1FBQzlCLElBQUksaUJBQVEsQ0FBQyxPQUFPLEVBQUUsb0NBQW9DLEVBQUU7WUFDMUQsTUFBTSxFQUFFLElBQUk7WUFDWixLQUFLLEVBQUU7Z0JBQ0wsS0FBSztnQkFDTCx3REFBd0Q7Z0JBQ3hELDBFQUEwRTtnQkFDMUUsMEVBQTBFO2dCQUMxRSwwRUFBMEU7Z0JBQzFFLHdEQUF3RDtnQkFDeEQsSUFBSTtnQkFDSiw4RUFBOEU7Z0JBQzlFLDhFQUE4RTtnQkFDOUUsNEVBQTRFO2dCQUM1RSxxREFBcUQ7Z0JBQ3JELEtBQUs7Z0JBQ0wsb0RBQW9EO2dCQUNwRCxxREFBcUQ7Z0JBQ3JELEVBQUU7Z0JBQ0YsZ0VBQWdFO2dCQUNoRSxrR0FBa0c7Z0JBQ2xHLEVBQUU7Z0JBQ0YsMkJBQTJCO2dCQUMzQixvQkFBb0I7Z0JBQ3BCLHFCQUFxQjtnQkFDckIsR0FBRztnQkFDSCxFQUFFO2dCQUNGLHNFQUFzRTtnQkFDdEUsZ0NBQWdDO2dCQUNoQyx1QkFBdUI7Z0JBQ3ZCLEtBQUs7Z0JBQ0wsdUZBQXVGO2dCQUN2RixHQUFHO2dCQUNILEVBQUU7Z0JBQ0YseURBQXlEO2dCQUN6RCxtR0FBbUc7Z0JBQ25HLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRiwwQ0FBMEM7Z0JBQzFDLDZEQUE2RDtnQkFDN0QsNkZBQTZGO2dCQUM3RixHQUFHO2dCQUNILEVBQUU7Z0JBQ0YsK0VBQStFO2dCQUMvRSwwQ0FBMEM7Z0JBQzFDLDRDQUE0QztnQkFDNUMsZ0RBQWdEO2dCQUNoRCxxREFBcUQ7Z0JBQ3JELDZFQUE2RTtnQkFDN0UsbUJBQW1CO2dCQUNuQix1QkFBdUI7Z0JBQ3ZCLDZCQUE2QjtnQkFDN0IsaURBQWlEO2dCQUNqRCx5RUFBeUU7Z0JBQ3pFLEtBQUs7Z0JBQ0wsR0FBRztnQkFDSCxFQUFFO2dCQUNGLHlCQUF5QjtnQkFDekIsb0NBQW9DO2dCQUNwQyxvQkFBb0I7Z0JBQ3BCLCtGQUErRjtnQkFDL0YsdUNBQXVDO2dCQUN2QyxhQUFhO2dCQUNiLEtBQUs7Z0JBQ0wsRUFBRTtnQkFDRiwyREFBMkQ7Z0JBQzNELHVDQUF1QztnQkFDdkMsS0FBSztnQkFDTCxrQ0FBa0M7Z0JBQ2xDLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRixTQUFTO2FBQ1Y7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLGlCQUFRLENBQUMsT0FBTyxFQUFFLCtCQUErQixFQUFFO1lBQ3JELE1BQU0sRUFBRSxLQUFLO1lBQ2IsR0FBRyxFQUFFO2dCQUNILE9BQU8sRUFBRSxrQkFBa0I7Z0JBQzNCLGVBQWUsRUFBRTtvQkFDZixNQUFNLEVBQUUsSUFBSTtvQkFDWixPQUFPLEVBQUUsR0FBRztpQkFDYjtnQkFDRCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUM7Z0JBQ2pCLE9BQU8sRUFBRSxDQUFDLGNBQWMsQ0FBQzthQUMxQjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXpGRCw0REF5RkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKc29uRmlsZSwgVGV4dEZpbGUgfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgTm9kZVByb2plY3QgfSBmcm9tICdwcm9qZW4vbGliL2phdmFzY3JpcHQnO1xuXG4vKipcbiAqIFRoZSBleHRlbnNpb24gc3RlcCBvZiBgc3dhbXA6Ym9vdHN0cmFwYDogYSBOb2RlIHNjcmlwdCwgc28gaXQgcnVucyB0aGUgc2FtZVxuICogdW5kZXIgcHJvamVuJ3MgUG93ZXJTaGVsbCA1LjEgdGFzayBzaGVsbCBvbiBXaW5kb3dzIGFzIHVuZGVyIGJhc2gvc2gsIHRoYXRcbiAqIHB1bGxzIGV2ZXJ5IGV4dGVuc2lvbiBhdCB0aGUgdmVyc2lvbiBwaW5uZWQgaW4gdGhlIHJlcG8ncyBzd2FtcCBsb2NrZmlsZS5cbiAqIEZ1bGx5IGdlbmVyaWMg4oCUIG5vIHBlci1yZXBvIHBhcmFtZXRlcml6YXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBTb2Z0d2FyZUZhY3RvcnlCb290c3RyYXAge1xuICBjb25zdHJ1Y3Rvcihwcm9qZWN0OiBOb2RlUHJvamVjdCkge1xuICAgIG5ldyBUZXh0RmlsZShwcm9qZWN0LCAnc3dhbXAtYm9vdHN0cmFwL3B1bGwtZXh0ZW5zaW9ucy50cycsIHtcbiAgICAgIG1hcmtlcjogdHJ1ZSxcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgICcvKionLFxuICAgICAgICAnICogUHVsbHMgZWFjaCBzd2FtcCBleHRlbnNpb24gYXQgdGhlIHZlcnNpb24gcGlubmVkIGluJyxcbiAgICAgICAgJyAqIGV4dGVuc2lvbnMvbW9kZWxzL3Vwc3RyZWFtX2V4dGVuc2lvbnMuanNvbiwgc28gYSBmcmVzaCBjbG9uZSBydW5zIHRoZScsXG4gICAgICAgICcgKiBzYW1lIGV4dGVuc2lvbnMgYXMgdGhlIHJlc3Qgb2YgdGhlIHRlYW0sIGluY2x1ZGluZyBhbnkgdGhlIHJlcG8gYWRkZWQnLFxuICAgICAgICAnICogaXRzZWxmLiBBIHJlcG8gd2l0aCBubyBsb2NrZmlsZSB5ZXQgcHVsbHMgREVGQVVMVF9FWFRFTlNJT05TIGF0IHRoZWlyJyxcbiAgICAgICAgJyAqIGxhdGVzdCBzdGFibGUgdmVyc2lvbnMsIHdoaWNoIGNyZWF0ZXMgdGhlIGxvY2tmaWxlLicsXG4gICAgICAgICcgKicsXG4gICAgICAgICcgKiBBIHB1bGwgcmV3cml0ZXMgdGhlIGxvY2tmaWxlIGV2ZW4gYXQgYW4gaWRlbnRpY2FsIHZlcnNpb24sIGFuZCBvbiBXaW5kb3dzJyxcbiAgICAgICAgJyAqIGl0IHdyaXRlcyBiYWNrc2xhc2ggcGF0aHMgYW5kIGRlbGV0ZXMgdGhlIGNvbW1pdHRlZCBmaWxlcyBpdCB0cmFja3MgKGUuZy4nLFxuICAgICAgICAnICogLmNsYXVkZS9za2lsbHMvc29mdHdhcmUtZmFjdG9yeS8pLiBTbyBhZnRlcndhcmRzIHRoZSBsb2NrZmlsZSBhbmQgZXZlcnknLFxuICAgICAgICAnICogZ2l0LXRyYWNrZWQgZmlsZSBpdCBsaXN0cyBhcmUgcmVzdG9yZWQgZnJvbSBnaXQuJyxcbiAgICAgICAgJyAqLycsXG4gICAgICAgIFwiaW1wb3J0IHsgZXhlY0ZpbGVTeW5jIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcIixcbiAgICAgICAgXCJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tICdub2RlOmZzJztcIixcbiAgICAgICAgJycsXG4gICAgICAgIFwiY29uc3QgTE9DS0ZJTEUgPSAnZXh0ZW5zaW9ucy9tb2RlbHMvdXBzdHJlYW1fZXh0ZW5zaW9ucy5qc29uJztcIixcbiAgICAgICAgXCJjb25zdCBERUZBVUxUX0VYVEVOU0lPTlMgPSBbJ0Bzd2FtcC9zb2Z0d2FyZS1mYWN0b3J5JywgJ0B3ZWJmcmFtcC9naXRodWInLCAnQGdvb2RjcmFmdC9naXRodWInXTtcIixcbiAgICAgICAgJycsXG4gICAgICAgICdpbnRlcmZhY2UgTG9ja2ZpbGVFbnRyeSB7JyxcbiAgICAgICAgJyAgdmVyc2lvbjogc3RyaW5nOycsXG4gICAgICAgICcgIGZpbGVzPzogc3RyaW5nW107JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIHJlYWRMb2NrZmlsZSgpOiBSZWNvcmQ8c3RyaW5nLCBMb2NrZmlsZUVudHJ5PiB8IHVuZGVmaW5lZCB7JyxcbiAgICAgICAgJyAgaWYgKCFleGlzdHNTeW5jKExPQ0tGSUxFKSkgeycsXG4gICAgICAgICcgICAgcmV0dXJuIHVuZGVmaW5lZDsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgXCIgIHJldHVybiBKU09OLnBhcnNlKHJlYWRGaWxlU3luYyhMT0NLRklMRSwgJ3V0ZjgnKSkgYXMgUmVjb3JkPHN0cmluZywgTG9ja2ZpbGVFbnRyeT47XCIsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBydW4oY29tbWFuZDogc3RyaW5nLCBhcmdzOiBzdHJpbmdbXSk6IHN0cmluZyB7JyxcbiAgICAgICAgXCIgIHJldHVybiBleGVjRmlsZVN5bmMoY29tbWFuZCwgYXJncywgeyBlbmNvZGluZzogJ3V0ZjgnLCBzdGRpbzogWydpZ25vcmUnLCAncGlwZScsICdpbmhlcml0J10gfSk7XCIsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBwdWxsKGV4dGVuc2lvbjogc3RyaW5nKTogdm9pZCB7JyxcbiAgICAgICAgJyAgY29uc29sZS5sb2coYHN3YW1wIGV4dGVuc2lvbiBwdWxsICR7ZXh0ZW5zaW9ufSAtLWZvcmNlYCk7JyxcbiAgICAgICAgXCIgIGV4ZWNGaWxlU3luYygnc3dhbXAnLCBbJ2V4dGVuc2lvbicsICdwdWxsJywgZXh0ZW5zaW9uLCAnLS1mb3JjZSddLCB7IHN0ZGlvOiAnaW5oZXJpdCcgfSk7XCIsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiByZXN0b3JlVHJhY2tlZEZpbGVzKGxvY2tmaWxlOiBSZWNvcmQ8c3RyaW5nLCBMb2NrZmlsZUVudHJ5Pik6IHZvaWQgeycsXG4gICAgICAgICcgIGNvbnN0IGxpc3RlZCA9IE9iamVjdC52YWx1ZXMobG9ja2ZpbGUpJyxcbiAgICAgICAgJyAgICAuZmxhdE1hcCgoZW50cnkpID0+IGVudHJ5LmZpbGVzID8/IFtdKScsXG4gICAgICAgIFwiICAgIC5tYXAoKGZpbGUpID0+IGZpbGUucmVwbGFjZSgvXFxcXFxcXFwvZywgJy8nKSlcIixcbiAgICAgICAgXCIgICAgLmZpbHRlcigoZmlsZSkgPT4gIWZpbGUuc3RhcnRzV2l0aCgnLnN3YW1wLycpKTtcIixcbiAgICAgICAgXCIgIGNvbnN0IHRyYWNrZWQgPSBydW4oJ2dpdCcsIFsnbHMtZmlsZXMnLCAnLXonLCAnLS0nLCBMT0NLRklMRSwgLi4ubGlzdGVkXSlcIixcbiAgICAgICAgXCIgICAgLnNwbGl0KCdcXFxcMCcpXCIsXG4gICAgICAgICcgICAgLmZpbHRlcihCb29sZWFuKTsnLFxuICAgICAgICAnICBpZiAodHJhY2tlZC5sZW5ndGggPiAwKSB7JyxcbiAgICAgICAgXCIgICAgcnVuKCdnaXQnLCBbJ2NoZWNrb3V0JywgJy0tJywgLi4udHJhY2tlZF0pO1wiLFxuICAgICAgICAnICAgIGNvbnNvbGUubG9nKGBSZXN0b3JlZCAke3RyYWNrZWQubGVuZ3RofSB0cmFja2VkIGZpbGUocykgZnJvbSBnaXRgKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIG1haW4oKTogdm9pZCB7JyxcbiAgICAgICAgJyAgY29uc3QgbG9ja2ZpbGUgPSByZWFkTG9ja2ZpbGUoKTsnLFxuICAgICAgICAnICBpZiAoIWxvY2tmaWxlKSB7JyxcbiAgICAgICAgJyAgICBjb25zb2xlLmxvZyhgTm8gJHtMT0NLRklMRX0geWV0OiBwdWxsaW5nIHRoZSBsYXRlc3Qgc3RhYmxlIHNvZnR3YXJlLWZhY3RvcnkgZXh0ZW5zaW9uc2ApOycsXG4gICAgICAgICcgICAgREVGQVVMVF9FWFRFTlNJT05TLmZvckVhY2gocHVsbCk7JyxcbiAgICAgICAgJyAgICByZXR1cm47JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcnLFxuICAgICAgICAnICBmb3IgKGNvbnN0IFtuYW1lLCBlbnRyeV0gb2YgT2JqZWN0LmVudHJpZXMobG9ja2ZpbGUpKSB7JyxcbiAgICAgICAgJyAgICBwdWxsKGAke25hbWV9QCR7ZW50cnkudmVyc2lvbn1gKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJyAgcmVzdG9yZVRyYWNrZWRGaWxlcyhsb2NrZmlsZSk7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ21haW4oKTsnLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIG5ldyBKc29uRmlsZShwcm9qZWN0LCAnc3dhbXAtYm9vdHN0cmFwL3RzY29uZmlnLmpzb24nLCB7XG4gICAgICBtYXJrZXI6IGZhbHNlLFxuICAgICAgb2JqOiB7XG4gICAgICAgIGV4dGVuZHM6ICcuLi90c2NvbmZpZy5qc29uJyxcbiAgICAgICAgY29tcGlsZXJPcHRpb25zOiB7XG4gICAgICAgICAgbm9FbWl0OiB0cnVlLFxuICAgICAgICAgIHJvb3REaXI6ICcuJyxcbiAgICAgICAgfSxcbiAgICAgICAgaW5jbHVkZTogWycqLnRzJ10sXG4gICAgICAgIGV4Y2x1ZGU6IFsnbm9kZV9tb2R1bGVzJ10sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG4iXX0=
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU29mdHdhcmVGYWN0b3J5Qm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NvZnR3YXJlRmFjdG9yeUJvb3RzdHJhcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBNEM7QUFFNUMscURBQWtEO0FBRXJDLFFBQUEsd0JBQXdCLEdBQUcsMENBQTBDLENBQUM7QUFFbkYsTUFBTSxpQkFBaUIsR0FBc0Q7SUFDM0UsQ0FBQywrQkFBYyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsY0FBYyxDQUFDO0NBQzlELENBQUM7QUFVRjs7Ozs7OztHQU9HO0FBQ0gsTUFBYSx3QkFBd0I7SUFDbkMsWUFBWSxPQUFvQixFQUFFLE9BQXdDO1FBQ3hFLElBQUksaUJBQVEsQ0FBQyxPQUFPLEVBQUUsZ0NBQXdCLEVBQUU7WUFDOUMsTUFBTSxFQUFFLElBQUk7WUFDWixRQUFRLEVBQUUsSUFBSTtZQUNkLEdBQUcsRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ2pFLE1BQU0sU0FBUyxHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUM1QyxPQUFPLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3RDLENBQUMsQ0FBQyxDQUFDO1NBQ0osQ0FBQyxDQUFDO1FBRUgsSUFBSSxpQkFBUSxDQUFDLE9BQU8sRUFBRSxvQ0FBb0MsRUFBRTtZQUMxRCxNQUFNLEVBQUUsSUFBSTtZQUNaLEtBQUssRUFBRTtnQkFDTCxLQUFLO2dCQUNMLHdEQUF3RDtnQkFDeEQsMEVBQTBFO2dCQUMxRSwwRUFBMEU7Z0JBQzFFLDBFQUEwRTtnQkFDMUUsd0RBQXdEO2dCQUN4RCxJQUFJO2dCQUNKLDhFQUE4RTtnQkFDOUUsOEVBQThFO2dCQUM5RSw0RUFBNEU7Z0JBQzVFLHFEQUFxRDtnQkFDckQsSUFBSTtnQkFDSiw2RUFBNkU7Z0JBQzdFLHdFQUF3RTtnQkFDeEUsdUVBQXVFO2dCQUN2RSw4RUFBOEU7Z0JBQzlFLDJCQUEyQjtnQkFDM0IsS0FBSztnQkFDTCxvREFBb0Q7Z0JBQ3BELG9FQUFvRTtnQkFDcEUsRUFBRTtnQkFDRixnRUFBZ0U7Z0JBQ2hFLHlFQUF5RTtnQkFDekUsa0dBQWtHO2dCQUNsRyxFQUFFO2dCQUNGLDJCQUEyQjtnQkFDM0Isb0JBQW9CO2dCQUNwQixxQkFBcUI7Z0JBQ3JCLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRixzRUFBc0U7Z0JBQ3RFLGdDQUFnQztnQkFDaEMsdUJBQXVCO2dCQUN2QixLQUFLO2dCQUNMLHVGQUF1RjtnQkFDdkYsR0FBRztnQkFDSCxFQUFFO2dCQUNGLHlEQUF5RDtnQkFDekQsbUdBQW1HO2dCQUNuRyxHQUFHO2dCQUNILEVBQUU7Z0JBQ0YsMENBQTBDO2dCQUMxQyw2REFBNkQ7Z0JBQzdELDZGQUE2RjtnQkFDN0YsR0FBRztnQkFDSCxFQUFFO2dCQUNGLDZEQUE2RDtnQkFDN0QsMkNBQTJDO2dCQUMzQyxnQkFBZ0I7Z0JBQ2hCLEtBQUs7Z0JBQ0wscUdBQXFHO2dCQUNyRyxpR0FBaUc7Z0JBQ2pHLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRiwyRUFBMkU7Z0JBQzNFLDZDQUE2QztnQkFDN0MseUVBQXlFO2dCQUN6RSx3SEFBd0g7Z0JBQ3hILE9BQU87Z0JBQ1AsS0FBSztnQkFDTCxpREFBaUQ7Z0JBQ2pELGdEQUFnRDtnQkFDaEQsa0VBQWtFO2dCQUNsRSx5REFBeUQ7Z0JBQ3pELDZCQUE2QjtnQkFDN0IsOEJBQThCO2dCQUM5QixPQUFPO2dCQUNQLEtBQUs7Z0JBQ0wsaUJBQWlCO2dCQUNqQixHQUFHO2dCQUNILEVBQUU7Z0JBQ0YsMENBQTBDO2dCQUMxQyxzQ0FBc0M7Z0JBQ3RDLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRix1R0FBdUc7Z0JBQ3ZHLDBDQUEwQztnQkFDMUMsNENBQTRDO2dCQUM1QyxtQkFBbUI7Z0JBQ25CLHFEQUFxRDtnQkFDckQsc0VBQXNFO2dCQUN0RSw2QkFBNkI7Z0JBQzdCLGFBQWE7Z0JBQ2IsS0FBSztnQkFDTCxrRUFBa0U7Z0JBQ2xFLG1CQUFtQjtnQkFDbkIsdUJBQXVCO2dCQUN2Qiw2QkFBNkI7Z0JBQzdCLGlEQUFpRDtnQkFDakQseUVBQXlFO2dCQUN6RSxLQUFLO2dCQUNMLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRiw2RUFBNkU7Z0JBQzdFLGtEQUFrRDtnQkFDbEQsd0JBQXdCO2dCQUN4QiwrQ0FBK0M7Z0JBQy9DLE9BQU87Z0JBQ1AsS0FBSztnQkFDTCx1RUFBdUU7Z0JBQ3ZFLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRiwyQ0FBMkM7Z0JBQzNDLDBDQUEwQztnQkFDMUMsMkRBQTJEO2dCQUMzRCxnR0FBZ0c7Z0JBQ2hHLDhCQUE4QjtnQkFDOUIsYUFBYTtnQkFDYixLQUFLO2dCQUNMLDJDQUEyQztnQkFDM0MsaUNBQWlDO2dCQUNqQyxLQUFLO2dCQUNMLG1DQUFtQztnQkFDbkMsa0JBQWtCO2dCQUNsQiwyREFBMkQ7Z0JBQzNELG9IQUFvSDtnQkFDcEgsaUNBQWlDO2dCQUNqQyxLQUFLO2dCQUNMLG9GQUFvRjtnQkFDcEYsNkRBQTZEO2dCQUM3RCxHQUFHO2dCQUNILEVBQUU7Z0JBQ0YseUJBQXlCO2dCQUN6QixvQ0FBb0M7Z0JBQ3BDLG9CQUFvQjtnQkFDcEIsK0ZBQStGO2dCQUMvRix1Q0FBdUM7Z0JBQ3ZDLFlBQVk7Z0JBQ1osNkRBQTZEO2dCQUM3RCx5Q0FBeUM7Z0JBQ3pDLE9BQU87Z0JBQ1Asb0NBQW9DO2dCQUNwQyxLQUFLO2dCQUNMLDZCQUE2QjtnQkFDN0IsR0FBRztnQkFDSCxFQUFFO2dCQUNGLFNBQVM7YUFDVjtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksaUJBQVEsQ0FBQyxPQUFPLEVBQUUsK0JBQStCLEVBQUU7WUFDckQsTUFBTSxFQUFFLEtBQUs7WUFDYixHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxFQUFFLGtCQUFrQjtnQkFDM0IsZUFBZSxFQUFFO29CQUNmLE1BQU0sRUFBRSxJQUFJO29CQUNaLE9BQU8sRUFBRSxHQUFHO2lCQUNiO2dCQUNELE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQztnQkFDakIsT0FBTyxFQUFFLENBQUMsY0FBYyxDQUFDO2FBQzFCO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBdktELDREQXVLQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEpzb25GaWxlLCBUZXh0RmlsZSB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBOb2RlUHJvamVjdCB9IGZyb20gJ3Byb2plbi9saWIvamF2YXNjcmlwdCc7XG5pbXBvcnQgeyBXb3JrSXRlbVNvdXJjZSB9IGZyb20gJy4vV29ya0l0ZW1Tb3VyY2UnO1xuXG5leHBvcnQgY29uc3QgUkVRVUlSRURfRVhURU5TSU9OU19QQVRIID0gJ3N3YW1wLWJvb3RzdHJhcC9yZXF1aXJlZC1leHRlbnNpb25zLmpzb24nO1xuXG5jb25zdCBTT1VSQ0VfRVhURU5TSU9OUzogUGFydGlhbDxSZWNvcmQ8V29ya0l0ZW1Tb3VyY2UsIFtzdHJpbmcsIHN0cmluZ10+PiA9IHtcbiAgW1dvcmtJdGVtU291cmNlLkdJVEhVQl06IFsnQHdlYmZyYW1wL2dpdGh1YicsICcyMDI2LjA5LjA4LjEnXSxcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29mdHdhcmVGYWN0b3J5Qm9vdHN0cmFwT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgZW5hYmxlZCB3b3JrLWl0ZW0gc291cmNlcywgd2hvc2UgZXh0ZW5zaW9ucyBib290c3RyYXAga2VlcHMgYXQgb3JcbiAgICogYWJvdmUgdGhlaXIgbWluaW11bSB2ZXJzaW9ucy5cbiAgICovXG4gIHJlYWRvbmx5IHdvcmtJdGVtU291cmNlczogV29ya0l0ZW1Tb3VyY2VbXTtcbn1cblxuLyoqXG4gKiBUaGUgZXh0ZW5zaW9uIHN0ZXAgb2YgYHN3YW1wOmJvb3RzdHJhcGA6IGEgTm9kZSBzY3JpcHQsIHNvIGl0IHJ1bnMgdGhlIHNhbWVcbiAqIHVuZGVyIHByb2plbidzIFBvd2VyU2hlbGwgNS4xIHRhc2sgc2hlbGwgb24gV2luZG93cyBhcyB1bmRlciBiYXNoL3NoLCB0aGF0XG4gKiBwdWxscyBldmVyeSBleHRlbnNpb24gYXQgdGhlIHZlcnNpb24gcGlubmVkIGluIHRoZSByZXBvJ3Mgc3dhbXAgbG9ja2ZpbGUsXG4gKiB0aGVuIHJhaXNlcyBhbnkgZXh0ZW5zaW9uIGJlbG93IHRoZSBtaW5pbXVtIHRoZSBlbmFibGVkIHdvcmstaXRlbSBzb3VyY2VzXG4gKiBuZWVkLiBUaGUgc2NyaXB0IGlzIHRoZSBzYW1lIGZvciBldmVyeSBwcm9qZWN0OyB0aGUgbWluaW11bXMgY29tZSBmcm9tIHRoZVxuICogZ2VuZXJhdGVkIGByZXF1aXJlZC1leHRlbnNpb25zLmpzb25gLlxuICovXG5leHBvcnQgY2xhc3MgU29mdHdhcmVGYWN0b3J5Qm9vdHN0cmFwIHtcbiAgY29uc3RydWN0b3IocHJvamVjdDogTm9kZVByb2plY3QsIG9wdGlvbnM6IFNvZnR3YXJlRmFjdG9yeUJvb3RzdHJhcE9wdGlvbnMpIHtcbiAgICBuZXcgSnNvbkZpbGUocHJvamVjdCwgUkVRVUlSRURfRVhURU5TSU9OU19QQVRILCB7XG4gICAgICBtYXJrZXI6IHRydWUsXG4gICAgICByZWFkb25seTogdHJ1ZSxcbiAgICAgIG9iajogT2JqZWN0LmZyb21FbnRyaWVzKG9wdGlvbnMud29ya0l0ZW1Tb3VyY2VzLmZsYXRNYXAoKHNvdXJjZSkgPT4ge1xuICAgICAgICBjb25zdCBleHRlbnNpb24gPSBTT1VSQ0VfRVhURU5TSU9OU1tzb3VyY2VdO1xuICAgICAgICByZXR1cm4gZXh0ZW5zaW9uID8gW2V4dGVuc2lvbl0gOiBbXTtcbiAgICAgIH0pKSxcbiAgICB9KTtcblxuICAgIG5ldyBUZXh0RmlsZShwcm9qZWN0LCAnc3dhbXAtYm9vdHN0cmFwL3B1bGwtZXh0ZW5zaW9ucy50cycsIHtcbiAgICAgIG1hcmtlcjogdHJ1ZSxcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgICcvKionLFxuICAgICAgICAnICogUHVsbHMgZWFjaCBzd2FtcCBleHRlbnNpb24gYXQgdGhlIHZlcnNpb24gcGlubmVkIGluJyxcbiAgICAgICAgJyAqIGV4dGVuc2lvbnMvbW9kZWxzL3Vwc3RyZWFtX2V4dGVuc2lvbnMuanNvbiwgc28gYSBmcmVzaCBjbG9uZSBydW5zIHRoZScsXG4gICAgICAgICcgKiBzYW1lIGV4dGVuc2lvbnMgYXMgdGhlIHJlc3Qgb2YgdGhlIHRlYW0sIGluY2x1ZGluZyBhbnkgdGhlIHJlcG8gYWRkZWQnLFxuICAgICAgICAnICogaXRzZWxmLiBBIHJlcG8gd2l0aCBubyBsb2NrZmlsZSB5ZXQgcHVsbHMgREVGQVVMVF9FWFRFTlNJT05TIGF0IHRoZWlyJyxcbiAgICAgICAgJyAqIGxhdGVzdCBzdGFibGUgdmVyc2lvbnMsIHdoaWNoIGNyZWF0ZXMgdGhlIGxvY2tmaWxlLicsXG4gICAgICAgICcgKicsXG4gICAgICAgICcgKiBBIHB1bGwgcmV3cml0ZXMgdGhlIGxvY2tmaWxlIGV2ZW4gYXQgYW4gaWRlbnRpY2FsIHZlcnNpb24sIGFuZCBvbiBXaW5kb3dzJyxcbiAgICAgICAgJyAqIGl0IHdyaXRlcyBiYWNrc2xhc2ggcGF0aHMgYW5kIGRlbGV0ZXMgdGhlIGNvbW1pdHRlZCBmaWxlcyBpdCB0cmFja3MgKGUuZy4nLFxuICAgICAgICAnICogLmNsYXVkZS9za2lsbHMvc29mdHdhcmUtZmFjdG9yeS8pLiBTbyBhZnRlcndhcmRzIHRoZSBsb2NrZmlsZSBhbmQgZXZlcnknLFxuICAgICAgICAnICogZ2l0LXRyYWNrZWQgZmlsZSBpdCBsaXN0cyBhcmUgcmVzdG9yZWQgZnJvbSBnaXQuJyxcbiAgICAgICAgJyAqJyxcbiAgICAgICAgJyAqIFRoZW4gZWFjaCBleHRlbnNpb24gaW4gc3dhbXAtYm9vdHN0cmFwL3JlcXVpcmVkLWV4dGVuc2lvbnMuanNvbiB0aGF0IHRoZScsXG4gICAgICAgICcgKiBsb2NrZmlsZSBsYWNrcywgb3IgcGlucyBiZWxvdyB0aGUgbGlzdGVkIG1pbmltdW0sIGlzIHB1bGxlZCBhdCB0aGF0JyxcbiAgICAgICAgJyAqIG1pbmltdW0uIFRoZSB0cmFja2VkIGZpbGVzIGl0IGxpc3RzIGFyZSByZXN0b3JlZCBhZ2FpbiwgZXhjZXB0IHRoZScsXG4gICAgICAgICcgKiBsb2NrZmlsZSwgd2hvc2UgcGF0aHMgYXJlIG5vcm1hbGl6ZWQgdG8gZm9yd2FyZCBzbGFzaGVzIHNvIGl0IGlzIHRoZSBvbmx5JyxcbiAgICAgICAgJyAqIGNoYW5nZSBsZWZ0IHRvIGNvbW1pdC4nLFxuICAgICAgICAnICovJyxcbiAgICAgICAgXCJpbXBvcnQgeyBleGVjRmlsZVN5bmMgfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1wiLFxuICAgICAgICBcImltcG9ydCB7IGV4aXN0c1N5bmMsIHJlYWRGaWxlU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gJ25vZGU6ZnMnO1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgXCJjb25zdCBMT0NLRklMRSA9ICdleHRlbnNpb25zL21vZGVscy91cHN0cmVhbV9leHRlbnNpb25zLmpzb24nO1wiLFxuICAgICAgICBcImNvbnN0IFJFUVVJUkVEX0VYVEVOU0lPTlMgPSAnc3dhbXAtYm9vdHN0cmFwL3JlcXVpcmVkLWV4dGVuc2lvbnMuanNvbic7XCIsXG4gICAgICAgIFwiY29uc3QgREVGQVVMVF9FWFRFTlNJT05TID0gWydAc3dhbXAvc29mdHdhcmUtZmFjdG9yeScsICdAd2ViZnJhbXAvZ2l0aHViJywgJ0Bnb29kY3JhZnQvZ2l0aHViJ107XCIsXG4gICAgICAgICcnLFxuICAgICAgICAnaW50ZXJmYWNlIExvY2tmaWxlRW50cnkgeycsXG4gICAgICAgICcgIHZlcnNpb246IHN0cmluZzsnLFxuICAgICAgICAnICBmaWxlcz86IHN0cmluZ1tdOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiByZWFkTG9ja2ZpbGUoKTogUmVjb3JkPHN0cmluZywgTG9ja2ZpbGVFbnRyeT4gfCB1bmRlZmluZWQgeycsXG4gICAgICAgICcgIGlmICghZXhpc3RzU3luYyhMT0NLRklMRSkpIHsnLFxuICAgICAgICAnICAgIHJldHVybiB1bmRlZmluZWQ7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgIFwiICByZXR1cm4gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMoTE9DS0ZJTEUsICd1dGY4JykpIGFzIFJlY29yZDxzdHJpbmcsIExvY2tmaWxlRW50cnk+O1wiLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gcnVuKGNvbW1hbmQ6IHN0cmluZywgYXJnczogc3RyaW5nW10pOiBzdHJpbmcgeycsXG4gICAgICAgIFwiICByZXR1cm4gZXhlY0ZpbGVTeW5jKGNvbW1hbmQsIGFyZ3MsIHsgZW5jb2Rpbmc6ICd1dGY4Jywgc3RkaW86IFsnaWdub3JlJywgJ3BpcGUnLCAnaW5oZXJpdCddIH0pO1wiLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gcHVsbChleHRlbnNpb246IHN0cmluZyk6IHZvaWQgeycsXG4gICAgICAgICcgIGNvbnNvbGUubG9nKGBzd2FtcCBleHRlbnNpb24gcHVsbCAke2V4dGVuc2lvbn0gLS1mb3JjZWApOycsXG4gICAgICAgIFwiICBleGVjRmlsZVN5bmMoJ3N3YW1wJywgWydleHRlbnNpb24nLCAncHVsbCcsIGV4dGVuc2lvbiwgJy0tZm9yY2UnXSwgeyBzdGRpbzogJ2luaGVyaXQnIH0pO1wiLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gcmVhZFJlcXVpcmVkRXh0ZW5zaW9ucygpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHsnLFxuICAgICAgICAnICBpZiAoIWV4aXN0c1N5bmMoUkVRVUlSRURfRVhURU5TSU9OUykpIHsnLFxuICAgICAgICAnICAgIHJldHVybiB7fTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgXCIgIGNvbnN0IHJlcXVpcmVkID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMoUkVRVUlSRURfRVhURU5TSU9OUywgJ3V0ZjgnKSkgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcIixcbiAgICAgICAgXCIgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMocmVxdWlyZWQpLmZpbHRlcigoW25hbWVdKSA9PiBuYW1lLnN0YXJ0c1dpdGgoJ0AnKSkpO1wiLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gaXNPbGRlcih2ZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQsIG1pbmltdW06IHN0cmluZyk6IGJvb2xlYW4geycsXG4gICAgICAgICcgIGZvciAoY29uc3QgdmFsdWUgb2YgW3ZlcnNpb24sIG1pbmltdW1dKSB7JyxcbiAgICAgICAgXCIgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycgfHwgIS9eXFxcXGQrKFxcXFwuXFxcXGQrKSokLy50ZXN0KHZhbHVlKSkge1wiLFxuICAgICAgICAnICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29tcGFyZSBleHRlbnNpb24gdmVyc2lvbiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX06IGV4cGVjdGVkIGRpZ2l0cyBzZXBhcmF0ZWQgYnkgZG90c2ApOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgIH0nLFxuICAgICAgICBcIiAgY29uc3QgaGF2ZSA9IHZlcnNpb24hLnNwbGl0KCcuJykubWFwKE51bWJlcik7XCIsXG4gICAgICAgIFwiICBjb25zdCB3YW50ID0gbWluaW11bS5zcGxpdCgnLicpLm1hcChOdW1iZXIpO1wiLFxuICAgICAgICAnICBmb3IgKGxldCBpID0gMDsgaSA8IE1hdGgubWF4KGhhdmUubGVuZ3RoLCB3YW50Lmxlbmd0aCk7IGkrKykgeycsXG4gICAgICAgICcgICAgY29uc3QgZGlmZmVyZW5jZSA9IChoYXZlW2ldID8/IDApIC0gKHdhbnRbaV0gPz8gMCk7JyxcbiAgICAgICAgJyAgICBpZiAoZGlmZmVyZW5jZSAhPT0gMCkgeycsXG4gICAgICAgICcgICAgICByZXR1cm4gZGlmZmVyZW5jZSA8IDA7JyxcbiAgICAgICAgJyAgICB9JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIHJldHVybiBmYWxzZTsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gdG9Qb3NpeChmaWxlOiBzdHJpbmcpOiBzdHJpbmcgeycsXG4gICAgICAgIFwiICByZXR1cm4gZmlsZS5yZXBsYWNlKC9cXFxcXFxcXC9nLCAnLycpO1wiLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gcmVzdG9yZVRyYWNrZWRGaWxlcyhsb2NrZmlsZTogUmVjb3JkPHN0cmluZywgTG9ja2ZpbGVFbnRyeT4sIGluY2x1ZGVMb2NrZmlsZSA9IHRydWUpOiB2b2lkIHsnLFxuICAgICAgICAnICBjb25zdCBsaXN0ZWQgPSBPYmplY3QudmFsdWVzKGxvY2tmaWxlKScsXG4gICAgICAgICcgICAgLmZsYXRNYXAoKGVudHJ5KSA9PiBlbnRyeS5maWxlcyA/PyBbXSknLFxuICAgICAgICAnICAgIC5tYXAodG9Qb3NpeCknLFxuICAgICAgICBcIiAgICAuZmlsdGVyKChmaWxlKSA9PiAhZmlsZS5zdGFydHNXaXRoKCcuc3dhbXAvJykpO1wiLFxuICAgICAgICAnICBjb25zdCBwYXRocyA9IFsuLi4oaW5jbHVkZUxvY2tmaWxlID8gW0xPQ0tGSUxFXSA6IFtdKSwgLi4ubGlzdGVkXTsnLFxuICAgICAgICAnICBpZiAocGF0aHMubGVuZ3RoID09PSAwKSB7JyxcbiAgICAgICAgJyAgICByZXR1cm47JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgIFwiICBjb25zdCB0cmFja2VkID0gcnVuKCdnaXQnLCBbJ2xzLWZpbGVzJywgJy16JywgJy0tJywgLi4ucGF0aHNdKVwiLFxuICAgICAgICBcIiAgICAuc3BsaXQoJ1xcXFwwJylcIixcbiAgICAgICAgJyAgICAuZmlsdGVyKEJvb2xlYW4pOycsXG4gICAgICAgICcgIGlmICh0cmFja2VkLmxlbmd0aCA+IDApIHsnLFxuICAgICAgICBcIiAgICBydW4oJ2dpdCcsIFsnY2hlY2tvdXQnLCAnLS0nLCAuLi50cmFja2VkXSk7XCIsXG4gICAgICAgICcgICAgY29uc29sZS5sb2coYFJlc3RvcmVkICR7dHJhY2tlZC5sZW5ndGh9IHRyYWNrZWQgZmlsZShzKSBmcm9tIGdpdGApOycsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gbm9ybWFsaXplTG9ja2ZpbGUobG9ja2ZpbGU6IFJlY29yZDxzdHJpbmcsIExvY2tmaWxlRW50cnk+KTogdm9pZCB7JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBlbnRyeSBvZiBPYmplY3QudmFsdWVzKGxvY2tmaWxlKSkgeycsXG4gICAgICAgICcgICAgaWYgKGVudHJ5LmZpbGVzKSB7JyxcbiAgICAgICAgJyAgICAgIGVudHJ5LmZpbGVzID0gZW50cnkuZmlsZXMubWFwKHRvUG9zaXgpOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnICB3cml0ZUZpbGVTeW5jKExPQ0tGSUxFLCBgJHtKU09OLnN0cmluZ2lmeShsb2NrZmlsZSwgbnVsbCwgMil9XFxcXG5gKTsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gcHVsbFJlcXVpcmVkRXh0ZW5zaW9ucygpOiB2b2lkIHsnLFxuICAgICAgICAnICBjb25zdCBsb2NrZmlsZSA9IHJlYWRMb2NrZmlsZSgpID8/IHt9OycsXG4gICAgICAgICcgIGNvbnN0IG5lZWRlZCA9IE9iamVjdC5lbnRyaWVzKHJlYWRSZXF1aXJlZEV4dGVuc2lvbnMoKSknLFxuICAgICAgICAnICAgIC5maWx0ZXIoKFtuYW1lLCBtaW5pbXVtXSkgPT4gIWxvY2tmaWxlW25hbWVdIHx8IGlzT2xkZXIobG9ja2ZpbGVbbmFtZV0udmVyc2lvbiwgbWluaW11bSkpOycsXG4gICAgICAgICcgIGlmIChuZWVkZWQubGVuZ3RoID09PSAwKSB7JyxcbiAgICAgICAgJyAgICByZXR1cm47JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIGZvciAoY29uc3QgW25hbWUsIG1pbmltdW1dIG9mIG5lZWRlZCkgeycsXG4gICAgICAgICcgICAgcHVsbChgJHtuYW1lfUAke21pbmltdW19YCk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIGNvbnN0IHVwZGF0ZWQgPSByZWFkTG9ja2ZpbGUoKTsnLFxuICAgICAgICAnICBpZiAodXBkYXRlZCkgeycsXG4gICAgICAgICcgICAgY29uc3QgcHVsbGVkID0gbmV3IFNldChuZWVkZWQubWFwKChbbmFtZV0pID0+IG5hbWUpKTsnLFxuICAgICAgICAnICAgIHJlc3RvcmVUcmFja2VkRmlsZXMoT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKHVwZGF0ZWQpLmZpbHRlcigoW25hbWVdKSA9PiAhcHVsbGVkLmhhcyhuYW1lKSkpLCBmYWxzZSk7JyxcbiAgICAgICAgJyAgICBub3JtYWxpemVMb2NrZmlsZSh1cGRhdGVkKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgXCIgIGNvbnN0IHBpbm5lZCA9IG5lZWRlZC5tYXAoKFtuYW1lLCBtaW5pbXVtXSkgPT4gYCR7bmFtZX1AJHttaW5pbXVtfWApLmpvaW4oJywgJyk7XCIsXG4gICAgICAgICcgIGNvbnNvbGUubG9nKGBDb21taXQgJHtMT0NLRklMRX06IGl0IG5vdyBwaW5zICR7cGlubmVkfWApOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBtYWluKCk6IHZvaWQgeycsXG4gICAgICAgICcgIGNvbnN0IGxvY2tmaWxlID0gcmVhZExvY2tmaWxlKCk7JyxcbiAgICAgICAgJyAgaWYgKCFsb2NrZmlsZSkgeycsXG4gICAgICAgICcgICAgY29uc29sZS5sb2coYE5vICR7TE9DS0ZJTEV9IHlldDogcHVsbGluZyB0aGUgbGF0ZXN0IHN0YWJsZSBzb2Z0d2FyZS1mYWN0b3J5IGV4dGVuc2lvbnNgKTsnLFxuICAgICAgICAnICAgIERFRkFVTFRfRVhURU5TSU9OUy5mb3JFYWNoKHB1bGwpOycsXG4gICAgICAgICcgIH0gZWxzZSB7JyxcbiAgICAgICAgJyAgICBmb3IgKGNvbnN0IFtuYW1lLCBlbnRyeV0gb2YgT2JqZWN0LmVudHJpZXMobG9ja2ZpbGUpKSB7JyxcbiAgICAgICAgJyAgICAgIHB1bGwoYCR7bmFtZX1AJHtlbnRyeS52ZXJzaW9ufWApOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgICAgcmVzdG9yZVRyYWNrZWRGaWxlcyhsb2NrZmlsZSk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIHB1bGxSZXF1aXJlZEV4dGVuc2lvbnMoKTsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnbWFpbigpOycsXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgbmV3IEpzb25GaWxlKHByb2plY3QsICdzd2FtcC1ib290c3RyYXAvdHNjb25maWcuanNvbicsIHtcbiAgICAgIG1hcmtlcjogZmFsc2UsXG4gICAgICBvYmo6IHtcbiAgICAgICAgZXh0ZW5kczogJy4uL3RzY29uZmlnLmpzb24nLFxuICAgICAgICBjb21waWxlck9wdGlvbnM6IHtcbiAgICAgICAgICBub0VtaXQ6IHRydWUsXG4gICAgICAgICAgcm9vdERpcjogJy4nLFxuICAgICAgICB9LFxuICAgICAgICBpbmNsdWRlOiBbJyoudHMnXSxcbiAgICAgICAgZXhjbHVkZTogWydub2RlX21vZHVsZXMnXSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,5 +1,6 @@
1
1
  import { NodeProject } from 'projen/lib/javascript';
2
2
  import { WorkflowActionVersions } from './WorkflowActionVersions';
3
+ import { WorkItemSourcesOptions } from './WorkItemSource';
3
4
  export interface SoftwareFactoryFilesOptions {
4
5
  /**
5
6
  * The bare repo name (e.g. `expense-tracker`), used to derive the factory's
@@ -33,6 +34,14 @@ export interface SoftwareFactoryFilesOptions {
33
34
  * @default - only the default files
34
35
  */
35
36
  readonly attestationFiles?: string[];
37
+ /**
38
+ * The trackers the factory's intake resolves work items from. Only the
39
+ * sources given are enabled, so `{ jira: {...} }` means Jira alone; leave a
40
+ * source out to turn it off.
41
+ *
42
+ * @default { github: {} }
43
+ */
44
+ readonly workItemSources?: WorkItemSourcesOptions;
36
45
  }
37
46
  /**
38
47
  * Backports exman's swamp "software factory" pattern
@@ -59,5 +68,9 @@ export interface SoftwareFactoryFilesOptions {
59
68
  * workflows that wire them together) is templated.
60
69
  */
61
70
  export declare class SoftwareFactoryFiles {
71
+ /**
72
+ * The work-item sources a project gets when it doesn't set `workItemSources`.
73
+ */
74
+ static readonly DEFAULT_WORK_ITEM_SOURCES: WorkItemSourcesOptions;
62
75
  constructor(project: NodeProject, options: SoftwareFactoryFilesOptions);
63
76
  }