construct-hub 0.4.430 → 0.4.432

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 (47) hide show
  1. package/.jsii +9 -9
  2. package/docs/operator-runbook.md +96 -0
  3. package/lib/backend/orchestration/index.d.ts +5 -1
  4. package/lib/backend/orchestration/index.js +9 -2
  5. package/lib/backend/orchestration/read-uninstallable-report.d.ts +7 -0
  6. package/lib/backend/orchestration/read-uninstallable-report.js +20 -0
  7. package/lib/backend/orchestration/read-uninstallable-report.lambda.bundle/index.js +60016 -0
  8. package/lib/backend/orchestration/read-uninstallable-report.lambda.bundle/index.js.map +7 -0
  9. package/lib/backend/orchestration/read-uninstallable-report.lambda.d.ts +13 -0
  10. package/lib/backend/orchestration/read-uninstallable-report.lambda.js +33 -0
  11. package/lib/backend/orchestration/retry-uninstallable-packages.d.ts +19 -0
  12. package/lib/backend/orchestration/retry-uninstallable-packages.js +100 -0
  13. package/lib/backend/package-stats/index.d.ts +15 -2
  14. package/lib/backend/package-stats/index.js +79 -21
  15. package/lib/backend/package-stats/package-stats-aggregator.d.ts +7 -0
  16. package/lib/backend/package-stats/package-stats-aggregator.js +20 -0
  17. package/lib/backend/package-stats/package-stats-aggregator.lambda.bundle/index.js +62489 -0
  18. package/lib/backend/package-stats/{package-stats.lambda.bundle → package-stats-aggregator.lambda.bundle}/index.js.map +4 -4
  19. package/lib/backend/package-stats/package-stats-aggregator.lambda.d.ts +13 -0
  20. package/lib/backend/package-stats/package-stats-aggregator.lambda.js +78 -0
  21. package/lib/backend/package-stats/package-stats-chunker.d.ts +7 -0
  22. package/lib/backend/package-stats/package-stats-chunker.js +20 -0
  23. package/lib/backend/package-stats/package-stats-chunker.lambda.bundle/index.js +60075 -0
  24. package/lib/backend/package-stats/package-stats-chunker.lambda.bundle/index.js.map +7 -0
  25. package/lib/backend/package-stats/package-stats-chunker.lambda.d.ts +6 -0
  26. package/lib/backend/package-stats/package-stats-chunker.lambda.js +25 -0
  27. package/lib/backend/package-stats/package-stats-processor.d.ts +7 -0
  28. package/lib/backend/package-stats/package-stats-processor.js +20 -0
  29. package/lib/backend/package-stats/{package-stats.lambda.bundle → package-stats-processor.lambda.bundle}/index.js +36 -2556
  30. package/lib/backend/package-stats/package-stats-processor.lambda.bundle/index.js.map +7 -0
  31. package/lib/backend/package-stats/package-stats-processor.lambda.d.ts +10 -0
  32. package/lib/backend/package-stats/package-stats-processor.lambda.js +41 -0
  33. package/lib/backend-dashboard.js +11 -6
  34. package/lib/construct-hub.d.ts +1 -1
  35. package/lib/construct-hub.js +12 -4
  36. package/lib/package-sources/code-artifact.js +1 -1
  37. package/lib/package-sources/npmjs.js +1 -1
  38. package/lib/package-tag/index.js +3 -3
  39. package/lib/package-tag-group/index.js +2 -2
  40. package/lib/preload-file/index.js +1 -1
  41. package/lib/s3/storage.js +1 -1
  42. package/lib/spdx-license.js +1 -1
  43. package/package.json +9 -3
  44. package/lib/backend/package-stats/package-stats.d.ts +0 -7
  45. package/lib/backend/package-stats/package-stats.js +0 -20
  46. package/lib/backend/package-stats/package-stats.lambda.d.ts +0 -25
  47. package/lib/backend/package-stats/package-stats.lambda.js +0 -79
@@ -0,0 +1,13 @@
1
+ export interface ReadUninstallableReportEvent {
2
+ readonly bucket: string;
3
+ readonly key: string;
4
+ }
5
+ export interface PackageInfo {
6
+ readonly originalPackage: string;
7
+ readonly packageName: string;
8
+ readonly packageVersion: string;
9
+ }
10
+ export interface ReadUninstallableReportResult {
11
+ readonly packages: PackageInfo[];
12
+ }
13
+ export declare function handler(event: ReadUninstallableReportEvent): Promise<ReadUninstallableReportResult>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handler = handler;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ const aws_lambda_shared_1 = require("../shared/aws.lambda-shared");
6
+ const compress_content_lambda_shared_1 = require("../shared/compress-content.lambda-shared");
7
+ function parsePackageName(packageString) {
8
+ const lastAtIndex = packageString.lastIndexOf('@');
9
+ if (lastAtIndex === -1) {
10
+ throw new Error(`Invalid package format: ${packageString}`);
11
+ }
12
+ const packageName = packageString.substring(0, lastAtIndex);
13
+ const packageVersion = packageString.substring(lastAtIndex + 1);
14
+ return {
15
+ originalPackage: packageString,
16
+ packageName,
17
+ packageVersion,
18
+ };
19
+ }
20
+ async function handler(event) {
21
+ const response = await aws_lambda_shared_1.S3_CLIENT.send(new client_s3_1.GetObjectCommand({
22
+ Bucket: event.bucket,
23
+ Key: event.key,
24
+ }));
25
+ if (!response.Body) {
26
+ throw new Error(`Object not found: s3://${event.bucket}/${event.key}`);
27
+ }
28
+ const decompressed = await (0, compress_content_lambda_shared_1.decompressContent)(response.Body, response.ContentEncoding);
29
+ const rawPackages = JSON.parse(decompressed);
30
+ const packages = rawPackages.map(parsePackageName);
31
+ return { packages };
32
+ }
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhZC11bmluc3RhbGxhYmxlLXJlcG9ydC5sYW1iZGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmFja2VuZC9vcmNoZXN0cmF0aW9uL3JlYWQtdW5pbnN0YWxsYWJsZS1yZXBvcnQubGFtYmRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBbUNBLDBCQXVCQztBQTFERCxrREFBc0Q7QUFDdEQsbUVBQXdEO0FBQ3hELDZGQUE2RTtBQWlCN0UsU0FBUyxnQkFBZ0IsQ0FBQyxhQUFxQjtJQUM3QyxNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ25ELElBQUksV0FBVyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsYUFBYSxFQUFFLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDNUQsTUFBTSxjQUFjLEdBQUcsYUFBYSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFaEUsT0FBTztRQUNMLGVBQWUsRUFBRSxhQUFhO1FBQzlCLFdBQVc7UUFDWCxjQUFjO0tBQ2YsQ0FBQztBQUNKLENBQUM7QUFFTSxLQUFLLFVBQVUsT0FBTyxDQUMzQixLQUFtQztJQUVuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLDZCQUFTLENBQUMsSUFBSSxDQUNuQyxJQUFJLDRCQUFnQixDQUFDO1FBQ25CLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtRQUNwQixHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7S0FDZixDQUFDLENBQ0gsQ0FBQztJQUVGLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbkIsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFBLGtEQUFpQixFQUMxQyxRQUFRLENBQUMsSUFBVyxFQUNwQixRQUFRLENBQUMsZUFBZSxDQUN6QixDQUFDO0lBRUYsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUM3QyxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFFbkQsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQ3RCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHZXRPYmplY3RDb21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXMzJztcbmltcG9ydCB7IFMzX0NMSUVOVCB9IGZyb20gJy4uL3NoYXJlZC9hd3MubGFtYmRhLXNoYXJlZCc7XG5pbXBvcnQgeyBkZWNvbXByZXNzQ29udGVudCB9IGZyb20gJy4uL3NoYXJlZC9jb21wcmVzcy1jb250ZW50LmxhbWJkYS1zaGFyZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlYWRVbmluc3RhbGxhYmxlUmVwb3J0RXZlbnQge1xuICByZWFkb25seSBidWNrZXQ6IHN0cmluZztcbiAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFja2FnZUluZm8ge1xuICByZWFkb25seSBvcmlnaW5hbFBhY2thZ2U6IHN0cmluZztcbiAgcmVhZG9ubHkgcGFja2FnZU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcGFja2FnZVZlcnNpb246IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWFkVW5pbnN0YWxsYWJsZVJlcG9ydFJlc3VsdCB7XG4gIHJlYWRvbmx5IHBhY2thZ2VzOiBQYWNrYWdlSW5mb1tdO1xufVxuXG5mdW5jdGlvbiBwYXJzZVBhY2thZ2VOYW1lKHBhY2thZ2VTdHJpbmc6IHN0cmluZyk6IFBhY2thZ2VJbmZvIHtcbiAgY29uc3QgbGFzdEF0SW5kZXggPSBwYWNrYWdlU3RyaW5nLmxhc3RJbmRleE9mKCdAJyk7XG4gIGlmIChsYXN0QXRJbmRleCA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcGFja2FnZSBmb3JtYXQ6ICR7cGFja2FnZVN0cmluZ31gKTtcbiAgfVxuXG4gIGNvbnN0IHBhY2thZ2VOYW1lID0gcGFja2FnZVN0cmluZy5zdWJzdHJpbmcoMCwgbGFzdEF0SW5kZXgpO1xuICBjb25zdCBwYWNrYWdlVmVyc2lvbiA9IHBhY2thZ2VTdHJpbmcuc3Vic3RyaW5nKGxhc3RBdEluZGV4ICsgMSk7XG5cbiAgcmV0dXJuIHtcbiAgICBvcmlnaW5hbFBhY2thZ2U6IHBhY2thZ2VTdHJpbmcsXG4gICAgcGFja2FnZU5hbWUsXG4gICAgcGFja2FnZVZlcnNpb24sXG4gIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKFxuICBldmVudDogUmVhZFVuaW5zdGFsbGFibGVSZXBvcnRFdmVudFxuKTogUHJvbWlzZTxSZWFkVW5pbnN0YWxsYWJsZVJlcG9ydFJlc3VsdD4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IFMzX0NMSUVOVC5zZW5kKFxuICAgIG5ldyBHZXRPYmplY3RDb21tYW5kKHtcbiAgICAgIEJ1Y2tldDogZXZlbnQuYnVja2V0LFxuICAgICAgS2V5OiBldmVudC5rZXksXG4gICAgfSlcbiAgKTtcblxuICBpZiAoIXJlc3BvbnNlLkJvZHkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE9iamVjdCBub3QgZm91bmQ6IHMzOi8vJHtldmVudC5idWNrZXR9LyR7ZXZlbnQua2V5fWApO1xuICB9XG5cbiAgY29uc3QgZGVjb21wcmVzc2VkID0gYXdhaXQgZGVjb21wcmVzc0NvbnRlbnQoXG4gICAgcmVzcG9uc2UuQm9keSBhcyBhbnksXG4gICAgcmVzcG9uc2UuQ29udGVudEVuY29kaW5nXG4gICk7XG5cbiAgY29uc3QgcmF3UGFja2FnZXMgPSBKU09OLnBhcnNlKGRlY29tcHJlc3NlZCk7XG4gIGNvbnN0IHBhY2thZ2VzID0gcmF3UGFja2FnZXMubWFwKHBhcnNlUGFja2FnZU5hbWUpO1xuXG4gIHJldHVybiB7IHBhY2thZ2VzIH07XG59XG4iXX0=
@@ -0,0 +1,19 @@
1
+ import { IBucket } from 'aws-cdk-lib/aws-s3';
2
+ import { IStateMachine, StateMachine } from 'aws-cdk-lib/aws-stepfunctions';
3
+ import { Construct } from 'constructs';
4
+ export interface RetryUninstallablePackagesProps {
5
+ readonly bucket: IBucket;
6
+ readonly orchestrationStateMachine: IStateMachine;
7
+ }
8
+ /**
9
+ * State machine that retries processing of uninstallable packages.
10
+ *
11
+ * This workflow:
12
+ * 1. Reads the uninstallable packages report
13
+ * 2. Triggers main orchestration for each package
14
+ * 3. Ends after processing all packages
15
+ */
16
+ export declare class RetryUninstallablePackages extends Construct {
17
+ readonly stateMachine: StateMachine;
18
+ constructor(scope: Construct, id: string, props: RetryUninstallablePackagesProps);
19
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RetryUninstallablePackages = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_logs_1 = require("aws-cdk-lib/aws-logs");
6
+ const aws_stepfunctions_1 = require("aws-cdk-lib/aws-stepfunctions");
7
+ const tasks = require("aws-cdk-lib/aws-stepfunctions-tasks");
8
+ const constructs_1 = require("constructs");
9
+ const read_uninstallable_report_1 = require("./read-uninstallable-report");
10
+ /**
11
+ * State machine that retries processing of uninstallable packages.
12
+ *
13
+ * This workflow:
14
+ * 1. Reads the uninstallable packages report
15
+ * 2. Triggers main orchestration for each package
16
+ * 3. Ends after processing all packages
17
+ */
18
+ class RetryUninstallablePackages extends constructs_1.Construct {
19
+ constructor(scope, id, props) {
20
+ super(scope, id);
21
+ const noReportFound = new aws_stepfunctions_1.Fail(this, 'No Report Found', {
22
+ error: 'NoReportFound',
23
+ cause: 'Uninstallable packages report not found at uninstallable-objects/data.json',
24
+ });
25
+ const noPackagesToRetry = new aws_stepfunctions_1.Succeed(this, 'No Packages to Retry');
26
+ const readReportFunction = new read_uninstallable_report_1.ReadUninstallableReport(this, 'ReadReportFunction', {
27
+ logRetention: aws_logs_1.RetentionDays.THREE_MONTHS,
28
+ });
29
+ props.bucket.grantRead(readReportFunction);
30
+ const readReport = new tasks.LambdaInvoke(this, 'Read Uninstallable Report', {
31
+ lambdaFunction: readReportFunction,
32
+ payload: aws_stepfunctions_1.TaskInput.fromObject({
33
+ bucket: props.bucket.bucketName,
34
+ key: 'uninstallable-objects/data.json',
35
+ }),
36
+ resultPath: '$.reportResponse',
37
+ });
38
+ readReport.addRetry({
39
+ errors: ['Lambda.Unknown'],
40
+ interval: aws_cdk_lib_1.Duration.seconds(2),
41
+ maxAttempts: 3,
42
+ backoffRate: 2.0,
43
+ });
44
+ readReport.addCatch(noReportFound, {
45
+ errors: ['States.TaskFailed'],
46
+ });
47
+ const packageRetryFailed = new aws_stepfunctions_1.Pass(this, 'Package Retry Failed', {
48
+ parameters: {
49
+ 'package.$': '$.originalPackage',
50
+ 'prefix.$': "States.Format('data/{}/v{}', $.packageName, $.packageVersion)",
51
+ 'error.$': '$.error',
52
+ },
53
+ });
54
+ const retryPackage = new tasks.StepFunctionsStartExecution(this, 'Retry Package', {
55
+ stateMachine: props.orchestrationStateMachine,
56
+ integrationPattern: aws_stepfunctions_1.IntegrationPattern.RUN_JOB,
57
+ input: aws_stepfunctions_1.TaskInput.fromObject({
58
+ bucket: props.bucket.bucketName,
59
+ assembly: {
60
+ 'key.$': "States.Format('data/{}/v{}/assembly.json', $.packageName, $.packageVersion)",
61
+ },
62
+ metadata: {
63
+ 'key.$': "States.Format('data/{}/v{}/metadata.json', $.packageName, $.packageVersion)",
64
+ },
65
+ package: {
66
+ 'key.$': "States.Format('data/{}/v{}/package.tgz', $.packageName, $.packageVersion)",
67
+ },
68
+ }),
69
+ });
70
+ retryPackage.addRetry({
71
+ errors: ['StepFunctions.ExecutionLimitExceeded'],
72
+ interval: aws_cdk_lib_1.Duration.seconds(60),
73
+ maxAttempts: 3,
74
+ backoffRate: 2.0,
75
+ });
76
+ retryPackage.addCatch(packageRetryFailed, {
77
+ errors: ['States.ALL'],
78
+ resultPath: '$.error',
79
+ });
80
+ const processEachPackage = new aws_stepfunctions_1.Map(this, 'Process Each Package', {
81
+ itemsPath: aws_stepfunctions_1.JsonPath.stringAt('$.reportResponse.Payload.packages'),
82
+ resultPath: aws_stepfunctions_1.JsonPath.DISCARD,
83
+ });
84
+ processEachPackage.itemProcessor(retryPackage);
85
+ const hasPackages = new aws_stepfunctions_1.Choice(this, 'Has Packages?')
86
+ .when(aws_stepfunctions_1.Condition.isPresent('$.reportResponse.Payload.packages[0]'), processEachPackage)
87
+ .otherwise(noPackagesToRetry);
88
+ const definition = readReport.next(hasPackages);
89
+ this.stateMachine = new aws_stepfunctions_1.StateMachine(this, 'Resource', {
90
+ definition,
91
+ stateMachineName: 'RetryUninstallablePackages',
92
+ timeout: aws_cdk_lib_1.Duration.hours(6),
93
+ tracingEnabled: true,
94
+ });
95
+ props.bucket.grantRead(this.stateMachine);
96
+ props.orchestrationStateMachine.grantStartExecution(this.stateMachine);
97
+ }
98
+ }
99
+ exports.RetryUninstallablePackages = RetryUninstallablePackages;
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV0cnktdW5pbnN0YWxsYWJsZS1wYWNrYWdlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kL29yY2hlc3RyYXRpb24vcmV0cnktdW5pbnN0YWxsYWJsZS1wYWNrYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBdUM7QUFDdkMsbURBQXFEO0FBRXJELHFFQVl1QztBQUN2Qyw2REFBNkQ7QUFDN0QsMkNBQXVDO0FBQ3ZDLDJFQUFzRTtBQU90RTs7Ozs7OztHQU9HO0FBQ0gsTUFBYSwwQkFBMkIsU0FBUSxzQkFBUztJQUd2RCxZQUNFLEtBQWdCLEVBQ2hCLEVBQVUsRUFDVixLQUFzQztRQUV0QyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sYUFBYSxHQUFHLElBQUksd0JBQUksQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLEVBQUU7WUFDdEQsS0FBSyxFQUFFLGVBQWU7WUFDdEIsS0FBSyxFQUNILDRFQUE0RTtTQUMvRSxDQUFDLENBQUM7UUFFSCxNQUFNLGlCQUFpQixHQUFHLElBQUksMkJBQU8sQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztRQUVwRSxNQUFNLGtCQUFrQixHQUFHLElBQUksbURBQXVCLENBQ3BELElBQUksRUFDSixvQkFBb0IsRUFDcEI7WUFDRSxZQUFZLEVBQUUsd0JBQWEsQ0FBQyxZQUFZO1NBQ3pDLENBQ0YsQ0FBQztRQUVGLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFFM0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxLQUFLLENBQUMsWUFBWSxDQUN2QyxJQUFJLEVBQ0osMkJBQTJCLEVBQzNCO1lBQ0UsY0FBYyxFQUFFLGtCQUFrQjtZQUNsQyxPQUFPLEVBQUUsNkJBQVMsQ0FBQyxVQUFVLENBQUM7Z0JBQzVCLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVU7Z0JBQy9CLEdBQUcsRUFBRSxpQ0FBaUM7YUFDdkMsQ0FBQztZQUNGLFVBQVUsRUFBRSxrQkFBa0I7U0FDL0IsQ0FDRixDQUFDO1FBRUYsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUNsQixNQUFNLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztZQUMxQixRQUFRLEVBQUUsc0JBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQzdCLFdBQVcsRUFBRSxDQUFDO1lBQ2QsV0FBVyxFQUFFLEdBQUc7U0FDakIsQ0FBQyxDQUFDO1FBRUgsVUFBVSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUU7WUFDakMsTUFBTSxFQUFFLENBQUMsbUJBQW1CLENBQUM7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLHdCQUFJLENBQUMsSUFBSSxFQUFFLHNCQUFzQixFQUFFO1lBQ2hFLFVBQVUsRUFBRTtnQkFDVixXQUFXLEVBQUUsbUJBQW1CO2dCQUNoQyxVQUFVLEVBQ1IsK0RBQStEO2dCQUNqRSxTQUFTLEVBQUUsU0FBUzthQUNyQjtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sWUFBWSxHQUFHLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUN4RCxJQUFJLEVBQ0osZUFBZSxFQUNmO1lBQ0UsWUFBWSxFQUFFLEtBQUssQ0FBQyx5QkFBeUI7WUFDN0Msa0JBQWtCLEVBQUUsc0NBQWtCLENBQUMsT0FBTztZQUM5QyxLQUFLLEVBQUUsNkJBQVMsQ0FBQyxVQUFVLENBQUM7Z0JBQzFCLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVU7Z0JBQy9CLFFBQVEsRUFBRTtvQkFDUixPQUFPLEVBQ0wsNkVBQTZFO2lCQUNoRjtnQkFDRCxRQUFRLEVBQUU7b0JBQ1IsT0FBTyxFQUNMLDZFQUE2RTtpQkFDaEY7Z0JBQ0QsT0FBTyxFQUFFO29CQUNQLE9BQU8sRUFDTCwyRUFBMkU7aUJBQzlFO2FBQ0YsQ0FBQztTQUNILENBQ0YsQ0FBQztRQUVGLFlBQVksQ0FBQyxRQUFRLENBQUM7WUFDcEIsTUFBTSxFQUFFLENBQUMsc0NBQXNDLENBQUM7WUFDaEQsUUFBUSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM5QixXQUFXLEVBQUUsQ0FBQztZQUNkLFdBQVcsRUFBRSxHQUFHO1NBQ2pCLENBQUMsQ0FBQztRQUVILFlBQVksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLEVBQUU7WUFDeEMsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDO1lBQ3RCLFVBQVUsRUFBRSxTQUFTO1NBQ3RCLENBQUMsQ0FBQztRQUVILE1BQU0sa0JBQWtCLEdBQUcsSUFBSSx1QkFBRyxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtZQUMvRCxTQUFTLEVBQUUsNEJBQVEsQ0FBQyxRQUFRLENBQUMsbUNBQW1DLENBQUM7WUFDakUsVUFBVSxFQUFFLDRCQUFRLENBQUMsT0FBTztTQUM3QixDQUFDLENBQUM7UUFFSCxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFL0MsTUFBTSxXQUFXLEdBQUcsSUFBSSwwQkFBTSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUM7YUFDbEQsSUFBSSxDQUNILDZCQUFTLENBQUMsU0FBUyxDQUFDLHNDQUFzQyxDQUFDLEVBQzNELGtCQUFrQixDQUNuQjthQUNBLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRWhDLE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFaEQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLGdDQUFZLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRTtZQUNyRCxVQUFVO1lBQ1YsZ0JBQWdCLEVBQUUsNEJBQTRCO1lBQzlDLE9BQU8sRUFBRSxzQkFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDMUIsY0FBYyxFQUFFLElBQUk7U0FDckIsQ0FBQyxDQUFDO1FBRUgsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDekUsQ0FBQztDQUNGO0FBM0hELGdFQTJIQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUmV0ZW50aW9uRGF5cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sb2dzJztcbmltcG9ydCB7IElCdWNrZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMnO1xuaW1wb3J0IHtcbiAgSVN0YXRlTWFjaGluZSxcbiAgU3RhdGVNYWNoaW5lLFxuICBTdWNjZWVkLFxuICBGYWlsLFxuICBQYXNzLFxuICBDaG9pY2UsXG4gIENvbmRpdGlvbixcbiAgTWFwLFxuICBKc29uUGF0aCxcbiAgSW50ZWdyYXRpb25QYXR0ZXJuLFxuICBUYXNrSW5wdXQsXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zJztcbmltcG9ydCAqIGFzIHRhc2tzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zLXRhc2tzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgUmVhZFVuaW5zdGFsbGFibGVSZXBvcnQgfSBmcm9tICcuL3JlYWQtdW5pbnN0YWxsYWJsZS1yZXBvcnQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJldHJ5VW5pbnN0YWxsYWJsZVBhY2thZ2VzUHJvcHMge1xuICByZWFkb25seSBidWNrZXQ6IElCdWNrZXQ7XG4gIHJlYWRvbmx5IG9yY2hlc3RyYXRpb25TdGF0ZU1hY2hpbmU6IElTdGF0ZU1hY2hpbmU7XG59XG5cbi8qKlxuICogU3RhdGUgbWFjaGluZSB0aGF0IHJldHJpZXMgcHJvY2Vzc2luZyBvZiB1bmluc3RhbGxhYmxlIHBhY2thZ2VzLlxuICpcbiAqIFRoaXMgd29ya2Zsb3c6XG4gKiAxLiBSZWFkcyB0aGUgdW5pbnN0YWxsYWJsZSBwYWNrYWdlcyByZXBvcnRcbiAqIDIuIFRyaWdnZXJzIG1haW4gb3JjaGVzdHJhdGlvbiBmb3IgZWFjaCBwYWNrYWdlXG4gKiAzLiBFbmRzIGFmdGVyIHByb2Nlc3NpbmcgYWxsIHBhY2thZ2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXRyeVVuaW5zdGFsbGFibGVQYWNrYWdlcyBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBzdGF0ZU1hY2hpbmU6IFN0YXRlTWFjaGluZTtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIHByb3BzOiBSZXRyeVVuaW5zdGFsbGFibGVQYWNrYWdlc1Byb3BzXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBub1JlcG9ydEZvdW5kID0gbmV3IEZhaWwodGhpcywgJ05vIFJlcG9ydCBGb3VuZCcsIHtcbiAgICAgIGVycm9yOiAnTm9SZXBvcnRGb3VuZCcsXG4gICAgICBjYXVzZTpcbiAgICAgICAgJ1VuaW5zdGFsbGFibGUgcGFja2FnZXMgcmVwb3J0IG5vdCBmb3VuZCBhdCB1bmluc3RhbGxhYmxlLW9iamVjdHMvZGF0YS5qc29uJyxcbiAgICB9KTtcblxuICAgIGNvbnN0IG5vUGFja2FnZXNUb1JldHJ5ID0gbmV3IFN1Y2NlZWQodGhpcywgJ05vIFBhY2thZ2VzIHRvIFJldHJ5Jyk7XG5cbiAgICBjb25zdCByZWFkUmVwb3J0RnVuY3Rpb24gPSBuZXcgUmVhZFVuaW5zdGFsbGFibGVSZXBvcnQoXG4gICAgICB0aGlzLFxuICAgICAgJ1JlYWRSZXBvcnRGdW5jdGlvbicsXG4gICAgICB7XG4gICAgICAgIGxvZ1JldGVudGlvbjogUmV0ZW50aW9uRGF5cy5USFJFRV9NT05USFMsXG4gICAgICB9XG4gICAgKTtcblxuICAgIHByb3BzLmJ1Y2tldC5ncmFudFJlYWQocmVhZFJlcG9ydEZ1bmN0aW9uKTtcblxuICAgIGNvbnN0IHJlYWRSZXBvcnQgPSBuZXcgdGFza3MuTGFtYmRhSW52b2tlKFxuICAgICAgdGhpcyxcbiAgICAgICdSZWFkIFVuaW5zdGFsbGFibGUgUmVwb3J0JyxcbiAgICAgIHtcbiAgICAgICAgbGFtYmRhRnVuY3Rpb246IHJlYWRSZXBvcnRGdW5jdGlvbixcbiAgICAgICAgcGF5bG9hZDogVGFza0lucHV0LmZyb21PYmplY3Qoe1xuICAgICAgICAgIGJ1Y2tldDogcHJvcHMuYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgICAga2V5OiAndW5pbnN0YWxsYWJsZS1vYmplY3RzL2RhdGEuanNvbicsXG4gICAgICAgIH0pLFxuICAgICAgICByZXN1bHRQYXRoOiAnJC5yZXBvcnRSZXNwb25zZScsXG4gICAgICB9XG4gICAgKTtcblxuICAgIHJlYWRSZXBvcnQuYWRkUmV0cnkoe1xuICAgICAgZXJyb3JzOiBbJ0xhbWJkYS5Vbmtub3duJ10sXG4gICAgICBpbnRlcnZhbDogRHVyYXRpb24uc2Vjb25kcygyKSxcbiAgICAgIG1heEF0dGVtcHRzOiAzLFxuICAgICAgYmFja29mZlJhdGU6IDIuMCxcbiAgICB9KTtcblxuICAgIHJlYWRSZXBvcnQuYWRkQ2F0Y2gobm9SZXBvcnRGb3VuZCwge1xuICAgICAgZXJyb3JzOiBbJ1N0YXRlcy5UYXNrRmFpbGVkJ10sXG4gICAgfSk7XG5cbiAgICBjb25zdCBwYWNrYWdlUmV0cnlGYWlsZWQgPSBuZXcgUGFzcyh0aGlzLCAnUGFja2FnZSBSZXRyeSBGYWlsZWQnLCB7XG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICdwYWNrYWdlLiQnOiAnJC5vcmlnaW5hbFBhY2thZ2UnLFxuICAgICAgICAncHJlZml4LiQnOlxuICAgICAgICAgIFwiU3RhdGVzLkZvcm1hdCgnZGF0YS97fS92e30nLCAkLnBhY2thZ2VOYW1lLCAkLnBhY2thZ2VWZXJzaW9uKVwiLFxuICAgICAgICAnZXJyb3IuJCc6ICckLmVycm9yJyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCByZXRyeVBhY2thZ2UgPSBuZXcgdGFza3MuU3RlcEZ1bmN0aW9uc1N0YXJ0RXhlY3V0aW9uKFxuICAgICAgdGhpcyxcbiAgICAgICdSZXRyeSBQYWNrYWdlJyxcbiAgICAgIHtcbiAgICAgICAgc3RhdGVNYWNoaW5lOiBwcm9wcy5vcmNoZXN0cmF0aW9uU3RhdGVNYWNoaW5lLFxuICAgICAgICBpbnRlZ3JhdGlvblBhdHRlcm46IEludGVncmF0aW9uUGF0dGVybi5SVU5fSk9CLFxuICAgICAgICBpbnB1dDogVGFza0lucHV0LmZyb21PYmplY3Qoe1xuICAgICAgICAgIGJ1Y2tldDogcHJvcHMuYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgICAgYXNzZW1ibHk6IHtcbiAgICAgICAgICAgICdrZXkuJCc6XG4gICAgICAgICAgICAgIFwiU3RhdGVzLkZvcm1hdCgnZGF0YS97fS92e30vYXNzZW1ibHkuanNvbicsICQucGFja2FnZU5hbWUsICQucGFja2FnZVZlcnNpb24pXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgJ2tleS4kJzpcbiAgICAgICAgICAgICAgXCJTdGF0ZXMuRm9ybWF0KCdkYXRhL3t9L3Z7fS9tZXRhZGF0YS5qc29uJywgJC5wYWNrYWdlTmFtZSwgJC5wYWNrYWdlVmVyc2lvbilcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBhY2thZ2U6IHtcbiAgICAgICAgICAgICdrZXkuJCc6XG4gICAgICAgICAgICAgIFwiU3RhdGVzLkZvcm1hdCgnZGF0YS97fS92e30vcGFja2FnZS50Z3onLCAkLnBhY2thZ2VOYW1lLCAkLnBhY2thZ2VWZXJzaW9uKVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfVxuICAgICk7XG5cbiAgICByZXRyeVBhY2thZ2UuYWRkUmV0cnkoe1xuICAgICAgZXJyb3JzOiBbJ1N0ZXBGdW5jdGlvbnMuRXhlY3V0aW9uTGltaXRFeGNlZWRlZCddLFxuICAgICAgaW50ZXJ2YWw6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgbWF4QXR0ZW1wdHM6IDMsXG4gICAgICBiYWNrb2ZmUmF0ZTogMi4wLFxuICAgIH0pO1xuXG4gICAgcmV0cnlQYWNrYWdlLmFkZENhdGNoKHBhY2thZ2VSZXRyeUZhaWxlZCwge1xuICAgICAgZXJyb3JzOiBbJ1N0YXRlcy5BTEwnXSxcbiAgICAgIHJlc3VsdFBhdGg6ICckLmVycm9yJyxcbiAgICB9KTtcblxuICAgIGNvbnN0IHByb2Nlc3NFYWNoUGFja2FnZSA9IG5ldyBNYXAodGhpcywgJ1Byb2Nlc3MgRWFjaCBQYWNrYWdlJywge1xuICAgICAgaXRlbXNQYXRoOiBKc29uUGF0aC5zdHJpbmdBdCgnJC5yZXBvcnRSZXNwb25zZS5QYXlsb2FkLnBhY2thZ2VzJyksXG4gICAgICByZXN1bHRQYXRoOiBKc29uUGF0aC5ESVNDQVJELFxuICAgIH0pO1xuXG4gICAgcHJvY2Vzc0VhY2hQYWNrYWdlLml0ZW1Qcm9jZXNzb3IocmV0cnlQYWNrYWdlKTtcblxuICAgIGNvbnN0IGhhc1BhY2thZ2VzID0gbmV3IENob2ljZSh0aGlzLCAnSGFzIFBhY2thZ2VzPycpXG4gICAgICAud2hlbihcbiAgICAgICAgQ29uZGl0aW9uLmlzUHJlc2VudCgnJC5yZXBvcnRSZXNwb25zZS5QYXlsb2FkLnBhY2thZ2VzWzBdJyksXG4gICAgICAgIHByb2Nlc3NFYWNoUGFja2FnZVxuICAgICAgKVxuICAgICAgLm90aGVyd2lzZShub1BhY2thZ2VzVG9SZXRyeSk7XG5cbiAgICBjb25zdCBkZWZpbml0aW9uID0gcmVhZFJlcG9ydC5uZXh0KGhhc1BhY2thZ2VzKTtcblxuICAgIHRoaXMuc3RhdGVNYWNoaW5lID0gbmV3IFN0YXRlTWFjaGluZSh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBkZWZpbml0aW9uLFxuICAgICAgc3RhdGVNYWNoaW5lTmFtZTogJ1JldHJ5VW5pbnN0YWxsYWJsZVBhY2thZ2VzJyxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLmhvdXJzKDYpLFxuICAgICAgdHJhY2luZ0VuYWJsZWQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBwcm9wcy5idWNrZXQuZ3JhbnRSZWFkKHRoaXMuc3RhdGVNYWNoaW5lKTtcbiAgICBwcm9wcy5vcmNoZXN0cmF0aW9uU3RhdGVNYWNoaW5lLmdyYW50U3RhcnRFeGVjdXRpb24odGhpcy5zdGF0ZU1hY2hpbmUpO1xuICB9XG59XG4iXX0=
@@ -3,6 +3,7 @@ import { Metric, MetricOptions } from 'aws-cdk-lib/aws-cloudwatch';
3
3
  import { IFunction } from 'aws-cdk-lib/aws-lambda';
4
4
  import { RetentionDays } from 'aws-cdk-lib/aws-logs';
5
5
  import type { IBucket } from 'aws-cdk-lib/aws-s3';
6
+ import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
6
7
  import { Construct } from 'constructs';
7
8
  import { Monitoring } from '../../monitoring';
8
9
  /**
@@ -36,6 +37,12 @@ export interface PackageStatsProps {
36
37
  * The key of the object storing the package stats.
37
38
  */
38
39
  readonly objectKey: string;
40
+ /**
41
+ * Number of packages to process per chunk.
42
+ *
43
+ * @default 100
44
+ */
45
+ readonly chunkSize?: number;
39
46
  }
40
47
  /**
41
48
  * Builds or re-builds the `stats.json` object in the designated bucket.
@@ -47,9 +54,15 @@ export declare class PackageStats extends Construct {
47
54
  */
48
55
  readonly bucket: IBucket;
49
56
  /**
50
- * The Lambda function that periodically updates stats.json.
57
+ * The Step Functions state machine that orchestrates stats processing.
58
+ */
59
+ readonly stateMachine: sfn.StateMachine;
60
+ /**
61
+ * The Lambda functions used in the state machine.
51
62
  */
52
- readonly handler: IFunction;
63
+ readonly chunkerFunction: IFunction;
64
+ readonly processorFunction: IFunction;
65
+ readonly aggregatorFunction: IFunction;
53
66
  /**
54
67
  * The key of the object storing the package stats.
55
68
  */
@@ -7,10 +7,13 @@ const events = require("aws-cdk-lib/aws-events");
7
7
  const targets = require("aws-cdk-lib/aws-events-targets");
8
8
  const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
9
9
  const aws_logs_1 = require("aws-cdk-lib/aws-logs");
10
+ const sfn = require("aws-cdk-lib/aws-stepfunctions");
11
+ const tasks = require("aws-cdk-lib/aws-stepfunctions-tasks");
10
12
  const constructs_1 = require("constructs");
11
13
  const constants_1 = require("./constants");
12
- const package_stats_1 = require("./package-stats");
13
- const deep_link_1 = require("../../deep-link");
14
+ const package_stats_aggregator_1 = require("./package-stats-aggregator");
15
+ const package_stats_chunker_1 = require("./package-stats-chunker");
16
+ const package_stats_processor_1 = require("./package-stats-processor");
14
17
  const runbook_url_1 = require("../../runbook-url");
15
18
  const constants_2 = require("../shared/constants");
16
19
  /**
@@ -21,36 +24,91 @@ class PackageStats extends constructs_1.Construct {
21
24
  super(scope, id);
22
25
  this.bucket = props.bucket;
23
26
  this.statsKey = props.objectKey;
24
- this.handler = new package_stats_1.PackageStats(this, 'Default', {
25
- description: `Creates the stats.json object in ${props.bucket.bucketName}`,
26
- environment: {
27
- CATALOG_BUCKET_NAME: this.bucket.bucketName,
28
- CATALOG_OBJECT_KEY: constants_2.CATALOG_KEY,
29
- STATS_BUCKET_NAME: this.bucket.bucketName,
30
- STATS_OBJECT_KEY: props.objectKey,
31
- },
27
+ const commonEnv = {
28
+ CATALOG_BUCKET_NAME: this.bucket.bucketName,
29
+ CATALOG_OBJECT_KEY: constants_2.CATALOG_KEY,
30
+ STATS_BUCKET_NAME: this.bucket.bucketName,
31
+ STATS_OBJECT_KEY: props.objectKey,
32
+ CHUNK_SIZE: (props.chunkSize ?? 100).toString(),
33
+ };
34
+ // Create Lambda functions
35
+ this.chunkerFunction = new package_stats_chunker_1.PackageStatsChunker(this, 'Chunker', {
36
+ description: 'Splits package list into chunks for parallel processing',
37
+ environment: commonEnv,
32
38
  logRetention: props.logRetention ?? aws_logs_1.RetentionDays.TEN_YEARS,
33
- memorySize: 256,
34
- reservedConcurrentExecutions: 1,
35
- timeout: aws_cdk_lib_1.Duration.minutes(15),
39
+ timeout: aws_cdk_lib_1.Duration.minutes(5),
36
40
  tracing: aws_lambda_1.Tracing.PASS_THROUGH,
37
41
  });
42
+ this.processorFunction = new package_stats_processor_1.PackageStatsProcessor(this, 'Processor', {
43
+ description: 'Processes a chunk of packages to get NPM stats',
44
+ environment: commonEnv,
45
+ logRetention: props.logRetention ?? aws_logs_1.RetentionDays.TEN_YEARS,
46
+ memorySize: 1024,
47
+ timeout: aws_cdk_lib_1.Duration.minutes(10),
48
+ tracing: aws_lambda_1.Tracing.PASS_THROUGH,
49
+ });
50
+ this.aggregatorFunction = new package_stats_aggregator_1.PackageStatsAggregator(this, 'Aggregator', {
51
+ description: 'Aggregates processed chunks into final stats.json',
52
+ environment: commonEnv,
53
+ logRetention: props.logRetention ?? aws_logs_1.RetentionDays.TEN_YEARS,
54
+ timeout: aws_cdk_lib_1.Duration.minutes(5),
55
+ tracing: aws_lambda_1.Tracing.PASS_THROUGH,
56
+ });
57
+ // Grant S3 permissions
58
+ this.bucket.grantReadWrite(this.chunkerFunction);
59
+ this.bucket.grantReadWrite(this.processorFunction);
60
+ this.bucket.grantReadWrite(this.aggregatorFunction);
61
+ // Create Step Functions state machine
62
+ const chunkPackages = new tasks.LambdaInvoke(this, 'ChunkPackages', {
63
+ lambdaFunction: this.chunkerFunction,
64
+ resultPath: '$.chunks',
65
+ });
66
+ const processChunksMap = new sfn.Map(this, 'ProcessChunksMap', {
67
+ itemsPath: '$.chunks.Payload.chunks',
68
+ maxConcurrency: 10,
69
+ resultPath: '$.processResults',
70
+ });
71
+ processChunksMap.itemProcessor(new tasks.LambdaInvoke(this, 'ProcessChunk', {
72
+ lambdaFunction: this.processorFunction,
73
+ inputPath: '$',
74
+ })
75
+ .addRetry({
76
+ errors: ['States.ALL'],
77
+ maxAttempts: 1,
78
+ backoffRate: 1,
79
+ interval: aws_cdk_lib_1.Duration.minutes(5),
80
+ })
81
+ .addCatch(new sfn.Pass(this, 'ProcessChunkError', {
82
+ result: sfn.Result.fromObject({ error: 'Failed to process chunk' }),
83
+ }), {
84
+ resultPath: '$.error',
85
+ }));
86
+ const aggregateResults = new tasks.LambdaInvoke(this, 'AggregateResults', {
87
+ lambdaFunction: this.aggregatorFunction,
88
+ inputPath: '$',
89
+ });
90
+ const definition = chunkPackages
91
+ .next(processChunksMap)
92
+ .next(aggregateResults);
93
+ this.stateMachine = new sfn.StateMachine(this, 'StateMachine', {
94
+ definition,
95
+ timeout: aws_cdk_lib_1.Duration.hours(6),
96
+ });
97
+ // Schedule the state machine
38
98
  const updatePeriod = props.updatePeriod ?? aws_cdk_lib_1.Duration.days(1);
39
99
  const rule = new events.Rule(this, 'Rule', {
40
100
  schedule: events.Schedule.rate(updatePeriod),
41
101
  });
42
- rule.addTarget(new targets.LambdaFunction(this.handler));
43
- this.bucket.grantReadWrite(this.handler);
44
- const failureAlarm = this.handler
45
- .metricErrors()
102
+ rule.addTarget(new targets.SfnStateMachine(this.stateMachine));
103
+ // Create alarms
104
+ const failureAlarm = this.stateMachine
105
+ .metricFailed()
46
106
  .createAlarm(scope, 'PackageStats/Failures', {
47
107
  alarmName: `${scope.node.path}/PackageStats/Failures`,
48
108
  alarmDescription: [
49
- 'The package stats function failed!',
109
+ 'The package stats state machine failed!',
50
110
  '',
51
111
  `RunBook: ${runbook_url_1.RUNBOOK_URL}`,
52
- '',
53
- `Direct link to Lambda function: ${(0, deep_link_1.lambdaFunctionUrl)(this.handler)}`,
54
112
  ].join('\n'),
55
113
  comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
56
114
  evaluationPeriods: 1,
@@ -70,4 +128,4 @@ class PackageStats extends constructs_1.Construct {
70
128
  }
71
129
  }
72
130
  exports.PackageStats = PackageStats;
73
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmFja2VuZC9wYWNrYWdlLXN0YXRzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUF1QztBQUN2QywrREFNb0M7QUFDcEMsaURBQWlEO0FBQ2pELDBEQUEwRDtBQUMxRCx1REFBNEQ7QUFDNUQsbURBQXFEO0FBRXJELDJDQUF1QztBQUN2QywyQ0FBNEQ7QUFDNUQsbURBQTBEO0FBQzFELCtDQUFvRDtBQUVwRCxtREFBZ0Q7QUFDaEQsbURBQWtEO0FBdUNsRDs7R0FFRztBQUNILE1BQWEsWUFBYSxTQUFRLHNCQUFTO0lBaUJ6QyxZQUFtQixLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUN2RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUMzQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFFaEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLDRCQUFPLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUMxQyxXQUFXLEVBQUUsb0NBQW9DLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO1lBQzFFLFdBQVcsRUFBRTtnQkFDWCxtQkFBbUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVU7Z0JBQzNDLGtCQUFrQixFQUFFLHVCQUFXO2dCQUMvQixpQkFBaUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVU7Z0JBQ3pDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxTQUFTO2FBQ2xDO1lBQ0QsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksd0JBQWEsQ0FBQyxTQUFTO1lBQzNELFVBQVUsRUFBRSxHQUFHO1lBQ2YsNEJBQTRCLEVBQUUsQ0FBQztZQUMvQixPQUFPLEVBQUUsc0JBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzdCLE9BQU8sRUFBRSxvQkFBTyxDQUFDLFlBQVk7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksSUFBSSxzQkFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLElBQUksR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRTtZQUN6QyxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1NBQzdDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRXpELElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUV6QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTzthQUM5QixZQUFZLEVBQUU7YUFDZCxXQUFXLENBQUMsS0FBSyxFQUFFLHVCQUF1QixFQUFFO1lBQzNDLFNBQVMsRUFBRSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSx3QkFBd0I7WUFDckQsZ0JBQWdCLEVBQUU7Z0JBQ2hCLG9DQUFvQztnQkFDcEMsRUFBRTtnQkFDRixZQUFZLHlCQUFXLEVBQUU7Z0JBQ3pCLEVBQUU7Z0JBQ0YsbUNBQW1DLElBQUEsNkJBQWlCLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO2FBQ3JFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNaLGtCQUFrQixFQUNoQixtQ0FBa0IsQ0FBQyxrQ0FBa0M7WUFDdkQsaUJBQWlCLEVBQUUsQ0FBQztZQUNwQixTQUFTLEVBQUUsQ0FBQztZQUNaLGdCQUFnQixFQUFFLGlDQUFnQixDQUFDLE9BQU87U0FDM0MsQ0FBQyxDQUFDO1FBQ0wsS0FBSyxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyx1QkFBdUIsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRU0sbUJBQW1CLENBQUMsSUFBb0I7UUFDN0MsT0FBTyxJQUFJLHVCQUFNLENBQUM7WUFDaEIsTUFBTSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUMzQixTQUFTLEVBQUUsMEJBQVMsQ0FBQyxPQUFPO1lBQzVCLEdBQUcsSUFBSTtZQUNQLFVBQVUsK0VBQTJDO1lBQ3JELFNBQVMsRUFBRSw2QkFBaUI7U0FDN0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBM0VELG9DQTJFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHtcbiAgQ29tcGFyaXNvbk9wZXJhdG9yLFxuICBNZXRyaWMsXG4gIE1ldHJpY09wdGlvbnMsXG4gIFN0YXRpc3RpYyxcbiAgVHJlYXRNaXNzaW5nRGF0YSxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0ICogYXMgZXZlbnRzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1ldmVudHMnO1xuaW1wb3J0ICogYXMgdGFyZ2V0cyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZXZlbnRzLXRhcmdldHMnO1xuaW1wb3J0IHsgSUZ1bmN0aW9uLCBUcmFjaW5nIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBSZXRlbnRpb25EYXlzIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0IHR5cGUgeyBJQnVja2V0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgTWV0cmljTmFtZSwgTUVUUklDU19OQU1FU1BBQ0UgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBQYWNrYWdlU3RhdHMgYXMgSGFuZGxlciB9IGZyb20gJy4vcGFja2FnZS1zdGF0cyc7XG5pbXBvcnQgeyBsYW1iZGFGdW5jdGlvblVybCB9IGZyb20gJy4uLy4uL2RlZXAtbGluayc7XG5pbXBvcnQgeyBNb25pdG9yaW5nIH0gZnJvbSAnLi4vLi4vbW9uaXRvcmluZyc7XG5pbXBvcnQgeyBSVU5CT09LX1VSTCB9IGZyb20gJy4uLy4uL3J1bmJvb2stdXJsJztcbmltcG9ydCB7IENBVEFMT0dfS0VZIH0gZnJvbSAnLi4vc2hhcmVkL2NvbnN0YW50cyc7XG5cbi8qKlxuICogUHJvcHMgZm9yIGBQYWNrYWdlU3RhdHNgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhY2thZ2VTdGF0c1Byb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBwYWNrYWdlIHN0b3JlIGJ1Y2tldCwgd2hpY2ggc2hvdWxkIGluY2x1ZGUgYm90aCB0aGVcbiAgICogY2F0YWxvZyBhbmQgc3RhdHMuXG4gICAqL1xuICByZWFkb25seSBidWNrZXQ6IElCdWNrZXQ7XG5cbiAgLyoqXG4gICAqIFRoZSBtb25pdG9yaW5nIGhhbmRsZXIgdG8gcmVnaXN0ZXIgYWxhcm1zIHdpdGguXG4gICAqL1xuICByZWFkb25seSBtb25pdG9yaW5nOiBNb25pdG9yaW5nO1xuXG4gIC8qKlxuICAgKiBIb3cgbG9uZyBzaG91bGQgZXhlY3V0aW9uIGxvZ3MgYmUgcmV0YWluZWQ/XG4gICAqXG4gICAqIEBkZWZhdWx0IFJldGVudGlvbkRheXMuVEVOX1lFQVJTXG4gICAqL1xuICByZWFkb25seSBsb2dSZXRlbnRpb24/OiBSZXRlbnRpb25EYXlzO1xuXG4gIC8qKlxuICAgKiBIb3cgZnJlcXVlbnRseSBzaG91bGQgdGhlIHN0YXRzIGJlIHVwZGF0ZWQ/XG4gICAqXG4gICAqIE5QTSB1cGRhdGVzIHRoZWlyIGRvd25sb2FkIHN0YXRzIG9uY2UgYSBkYXkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gMSBkYXlcbiAgICovXG4gIHJlYWRvbmx5IHVwZGF0ZVBlcmlvZD86IER1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUga2V5IG9mIHRoZSBvYmplY3Qgc3RvcmluZyB0aGUgcGFja2FnZSBzdGF0cy5cbiAgICovXG4gIHJlYWRvbmx5IG9iamVjdEtleTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBvciByZS1idWlsZHMgdGhlIGBzdGF0cy5qc29uYCBvYmplY3QgaW4gdGhlIGRlc2lnbmF0ZWQgYnVja2V0LlxuICovXG5leHBvcnQgY2xhc3MgUGFja2FnZVN0YXRzIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBwYWNrYWdlIHN0b3JlIGJ1Y2tldCwgd2hpY2ggc2hvdWxkIGluY2x1ZGUgYm90aCB0aGVcbiAgICogY2F0YWxvZyBhbmQgc3RhdHMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYnVja2V0OiBJQnVja2V0O1xuXG4gIC8qKlxuICAgKiBUaGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgcGVyaW9kaWNhbGx5IHVwZGF0ZXMgc3RhdHMuanNvbi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBoYW5kbGVyOiBJRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIFRoZSBrZXkgb2YgdGhlIG9iamVjdCBzdG9yaW5nIHRoZSBwYWNrYWdlIHN0YXRzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHN0YXRzS2V5OiBzdHJpbmc7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBQYWNrYWdlU3RhdHNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLmJ1Y2tldCA9IHByb3BzLmJ1Y2tldDtcbiAgICB0aGlzLnN0YXRzS2V5ID0gcHJvcHMub2JqZWN0S2V5O1xuXG4gICAgdGhpcy5oYW5kbGVyID0gbmV3IEhhbmRsZXIodGhpcywgJ0RlZmF1bHQnLCB7XG4gICAgICBkZXNjcmlwdGlvbjogYENyZWF0ZXMgdGhlIHN0YXRzLmpzb24gb2JqZWN0IGluICR7cHJvcHMuYnVja2V0LmJ1Y2tldE5hbWV9YCxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIENBVEFMT0dfQlVDS0VUX05BTUU6IHRoaXMuYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgIENBVEFMT0dfT0JKRUNUX0tFWTogQ0FUQUxPR19LRVksXG4gICAgICAgIFNUQVRTX0JVQ0tFVF9OQU1FOiB0aGlzLmJ1Y2tldC5idWNrZXROYW1lLFxuICAgICAgICBTVEFUU19PQkpFQ1RfS0VZOiBwcm9wcy5vYmplY3RLZXksXG4gICAgICB9LFxuICAgICAgbG9nUmV0ZW50aW9uOiBwcm9wcy5sb2dSZXRlbnRpb24gPz8gUmV0ZW50aW9uRGF5cy5URU5fWUVBUlMsXG4gICAgICBtZW1vcnlTaXplOiAyNTYsXG4gICAgICByZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zOiAxLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgICB0cmFjaW5nOiBUcmFjaW5nLlBBU1NfVEhST1VHSCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHVwZGF0ZVBlcmlvZCA9IHByb3BzLnVwZGF0ZVBlcmlvZCA/PyBEdXJhdGlvbi5kYXlzKDEpO1xuICAgIGNvbnN0IHJ1bGUgPSBuZXcgZXZlbnRzLlJ1bGUodGhpcywgJ1J1bGUnLCB7XG4gICAgICBzY2hlZHVsZTogZXZlbnRzLlNjaGVkdWxlLnJhdGUodXBkYXRlUGVyaW9kKSxcbiAgICB9KTtcbiAgICBydWxlLmFkZFRhcmdldChuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbih0aGlzLmhhbmRsZXIpKTtcblxuICAgIHRoaXMuYnVja2V0LmdyYW50UmVhZFdyaXRlKHRoaXMuaGFuZGxlcik7XG5cbiAgICBjb25zdCBmYWlsdXJlQWxhcm0gPSB0aGlzLmhhbmRsZXJcbiAgICAgIC5tZXRyaWNFcnJvcnMoKVxuICAgICAgLmNyZWF0ZUFsYXJtKHNjb3BlLCAnUGFja2FnZVN0YXRzL0ZhaWx1cmVzJywge1xuICAgICAgICBhbGFybU5hbWU6IGAke3Njb3BlLm5vZGUucGF0aH0vUGFja2FnZVN0YXRzL0ZhaWx1cmVzYCxcbiAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjogW1xuICAgICAgICAgICdUaGUgcGFja2FnZSBzdGF0cyBmdW5jdGlvbiBmYWlsZWQhJyxcbiAgICAgICAgICAnJyxcbiAgICAgICAgICBgUnVuQm9vazogJHtSVU5CT09LX1VSTH1gLFxuICAgICAgICAgICcnLFxuICAgICAgICAgIGBEaXJlY3QgbGluayB0byBMYW1iZGEgZnVuY3Rpb246ICR7bGFtYmRhRnVuY3Rpb25VcmwodGhpcy5oYW5kbGVyKX1gLFxuICAgICAgICBdLmpvaW4oJ1xcbicpLFxuICAgICAgICBjb21wYXJpc29uT3BlcmF0b3I6XG4gICAgICAgICAgQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiAxLFxuICAgICAgICB0aHJlc2hvbGQ6IDEsXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IFRyZWF0TWlzc2luZ0RhdGEuTUlTU0lORyxcbiAgICAgIH0pO1xuICAgIHByb3BzLm1vbml0b3JpbmcuYWRkTG93U2V2ZXJpdHlBbGFybSgnUGFja2FnZVN0YXRzIEZhaWx1cmVzJywgZmFpbHVyZUFsYXJtKTtcbiAgfVxuXG4gIHB1YmxpYyBtZXRyaWNQYWNrYWdlc0NvdW50KG9wdHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gbmV3IE1ldHJpYyh7XG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICBzdGF0aXN0aWM6IFN0YXRpc3RpYy5NQVhJTVVNLFxuICAgICAgLi4ub3B0cyxcbiAgICAgIG1ldHJpY05hbWU6IE1ldHJpY05hbWUuUkVHSVNURVJFRF9QQUNLQUdFU19XSVRIX1NUQVRTLFxuICAgICAgbmFtZXNwYWNlOiBNRVRSSUNTX05BTUVTUEFDRSxcbiAgICB9KTtcbiAgfVxufVxuIl19
131
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmFja2VuZC9wYWNrYWdlLXN0YXRzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUF1QztBQUN2QywrREFNb0M7QUFDcEMsaURBQWlEO0FBQ2pELDBEQUEwRDtBQUMxRCx1REFBNEQ7QUFDNUQsbURBQXFEO0FBRXJELHFEQUFxRDtBQUNyRCw2REFBNkQ7QUFDN0QsMkNBQXVDO0FBQ3ZDLDJDQUE0RDtBQUM1RCx5RUFBb0U7QUFDcEUsbUVBQThEO0FBQzlELHVFQUFrRTtBQUdsRSxtREFBZ0Q7QUFDaEQsbURBQWtEO0FBOENsRDs7R0FFRztBQUNILE1BQWEsWUFBYSxTQUFRLHNCQUFTO0lBd0J6QyxZQUFtQixLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUN2RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUMzQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFFaEMsTUFBTSxTQUFTLEdBQUc7WUFDaEIsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVO1lBQzNDLGtCQUFrQixFQUFFLHVCQUFXO1lBQy9CLGlCQUFpQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVTtZQUN6QyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsU0FBUztZQUNqQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRTtTQUNoRCxDQUFDO1FBRUYsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSwyQ0FBbUIsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQzlELFdBQVcsRUFBRSx5REFBeUQ7WUFDdEUsV0FBVyxFQUFFLFNBQVM7WUFDdEIsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksd0JBQWEsQ0FBQyxTQUFTO1lBQzNELE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDNUIsT0FBTyxFQUFFLG9CQUFPLENBQUMsWUFBWTtTQUM5QixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSwrQ0FBcUIsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFO1lBQ3BFLFdBQVcsRUFBRSxnREFBZ0Q7WUFDN0QsV0FBVyxFQUFFLFNBQVM7WUFDdEIsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksd0JBQWEsQ0FBQyxTQUFTO1lBQzNELFVBQVUsRUFBRSxJQUFJO1lBQ2hCLE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxFQUFFLG9CQUFPLENBQUMsWUFBWTtTQUM5QixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxpREFBc0IsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO1lBQ3ZFLFdBQVcsRUFBRSxtREFBbUQ7WUFDaEUsV0FBVyxFQUFFLFNBQVM7WUFDdEIsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksd0JBQWEsQ0FBQyxTQUFTO1lBQzNELE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDNUIsT0FBTyxFQUFFLG9CQUFPLENBQUMsWUFBWTtTQUM5QixDQUFDLENBQUM7UUFFSCx1QkFBdUI7UUFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRXBELHNDQUFzQztRQUN0QyxNQUFNLGFBQWEsR0FBRyxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRTtZQUNsRSxjQUFjLEVBQUUsSUFBSSxDQUFDLGVBQWU7WUFDcEMsVUFBVSxFQUFFLFVBQVU7U0FDdkIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFO1lBQzdELFNBQVMsRUFBRSx5QkFBeUI7WUFDcEMsY0FBYyxFQUFFLEVBQUU7WUFDbEIsVUFBVSxFQUFFLGtCQUFrQjtTQUMvQixDQUFDLENBQUM7UUFFSCxnQkFBZ0IsQ0FBQyxhQUFhLENBQzVCLElBQUksS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFO1lBQzNDLGNBQWMsRUFBRSxJQUFJLENBQUMsaUJBQWlCO1lBQ3RDLFNBQVMsRUFBRSxHQUFHO1NBQ2YsQ0FBQzthQUNDLFFBQVEsQ0FBQztZQUNSLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQztZQUN0QixXQUFXLEVBQUUsQ0FBQztZQUNkLFdBQVcsRUFBRSxDQUFDO1lBQ2QsUUFBUSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztTQUM5QixDQUFDO2FBQ0QsUUFBUSxDQUNQLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDdEMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxFQUFFLHlCQUF5QixFQUFFLENBQUM7U0FDcEUsQ0FBQyxFQUNGO1lBQ0UsVUFBVSxFQUFFLFNBQVM7U0FDdEIsQ0FDRixDQUNKLENBQUM7UUFFRixNQUFNLGdCQUFnQixHQUFHLElBQUksS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDeEUsY0FBYyxFQUFFLElBQUksQ0FBQyxrQkFBa0I7WUFDdkMsU0FBUyxFQUFFLEdBQUc7U0FDZixDQUFDLENBQUM7UUFFSCxNQUFNLFVBQVUsR0FBRyxhQUFhO2FBQzdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQzthQUN0QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUUxQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFO1lBQzdELFVBQVU7WUFDVixPQUFPLEVBQUUsc0JBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQzNCLENBQUMsQ0FBQztRQUVILDZCQUE2QjtRQUM3QixNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxJQUFJLHNCQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVELE1BQU0sSUFBSSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFO1lBQ3pDLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7U0FDN0MsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFFL0QsZ0JBQWdCO1FBQ2hCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZO2FBQ25DLFlBQVksRUFBRTthQUNkLFdBQVcsQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLEVBQUU7WUFDM0MsU0FBUyxFQUFFLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLHdCQUF3QjtZQUNyRCxnQkFBZ0IsRUFBRTtnQkFDaEIseUNBQXlDO2dCQUN6QyxFQUFFO2dCQUNGLFlBQVkseUJBQVcsRUFBRTthQUMxQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDWixrQkFBa0IsRUFDaEIsbUNBQWtCLENBQUMsa0NBQWtDO1lBQ3ZELGlCQUFpQixFQUFFLENBQUM7WUFDcEIsU0FBUyxFQUFFLENBQUM7WUFDWixnQkFBZ0IsRUFBRSxpQ0FBZ0IsQ0FBQyxPQUFPO1NBQzNDLENBQUMsQ0FBQztRQUNMLEtBQUssQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsdUJBQXVCLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVNLG1CQUFtQixDQUFDLElBQW9CO1FBQzdDLE9BQU8sSUFBSSx1QkFBTSxDQUFDO1lBQ2hCLE1BQU0sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDM0IsU0FBUyxFQUFFLDBCQUFTLENBQUMsT0FBTztZQUM1QixHQUFHLElBQUk7WUFDUCxVQUFVLCtFQUEyQztZQUNyRCxTQUFTLEVBQUUsNkJBQWlCO1NBQzdCLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXZKRCxvQ0F1SkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7XG4gIENvbXBhcmlzb25PcGVyYXRvcixcbiAgTWV0cmljLFxuICBNZXRyaWNPcHRpb25zLFxuICBTdGF0aXN0aWMsXG4gIFRyZWF0TWlzc2luZ0RhdGEsXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZXZlbnRzJztcbmltcG9ydCAqIGFzIHRhcmdldHMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWV2ZW50cy10YXJnZXRzJztcbmltcG9ydCB7IElGdW5jdGlvbiwgVHJhY2luZyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgUmV0ZW50aW9uRGF5cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sb2dzJztcbmltcG9ydCB0eXBlIHsgSUJ1Y2tldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgKiBhcyBzZm4gZnJvbSAnYXdzLWNkay1saWIvYXdzLXN0ZXBmdW5jdGlvbnMnO1xuaW1wb3J0ICogYXMgdGFza3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLXN0ZXBmdW5jdGlvbnMtdGFza3MnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBNZXRyaWNOYW1lLCBNRVRSSUNTX05BTUVTUEFDRSB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IFBhY2thZ2VTdGF0c0FnZ3JlZ2F0b3IgfSBmcm9tICcuL3BhY2thZ2Utc3RhdHMtYWdncmVnYXRvcic7XG5pbXBvcnQgeyBQYWNrYWdlU3RhdHNDaHVua2VyIH0gZnJvbSAnLi9wYWNrYWdlLXN0YXRzLWNodW5rZXInO1xuaW1wb3J0IHsgUGFja2FnZVN0YXRzUHJvY2Vzc29yIH0gZnJvbSAnLi9wYWNrYWdlLXN0YXRzLXByb2Nlc3Nvcic7XG5cbmltcG9ydCB7IE1vbml0b3JpbmcgfSBmcm9tICcuLi8uLi9tb25pdG9yaW5nJztcbmltcG9ydCB7IFJVTkJPT0tfVVJMIH0gZnJvbSAnLi4vLi4vcnVuYm9vay11cmwnO1xuaW1wb3J0IHsgQ0FUQUxPR19LRVkgfSBmcm9tICcuLi9zaGFyZWQvY29uc3RhbnRzJztcblxuLyoqXG4gKiBQcm9wcyBmb3IgYFBhY2thZ2VTdGF0c2AuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFja2FnZVN0YXRzUHJvcHMge1xuICAvKipcbiAgICogVGhlIHBhY2thZ2Ugc3RvcmUgYnVja2V0LCB3aGljaCBzaG91bGQgaW5jbHVkZSBib3RoIHRoZVxuICAgKiBjYXRhbG9nIGFuZCBzdGF0cy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldDogSUJ1Y2tldDtcblxuICAvKipcbiAgICogVGhlIG1vbml0b3JpbmcgaGFuZGxlciB0byByZWdpc3RlciBhbGFybXMgd2l0aC5cbiAgICovXG4gIHJlYWRvbmx5IG1vbml0b3Jpbmc6IE1vbml0b3Jpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyBsb25nIHNob3VsZCBleGVjdXRpb24gbG9ncyBiZSByZXRhaW5lZD9cbiAgICpcbiAgICogQGRlZmF1bHQgUmV0ZW50aW9uRGF5cy5URU5fWUVBUlNcbiAgICovXG4gIHJlYWRvbmx5IGxvZ1JldGVudGlvbj86IFJldGVudGlvbkRheXM7XG5cbiAgLyoqXG4gICAqIEhvdyBmcmVxdWVudGx5IHNob3VsZCB0aGUgc3RhdHMgYmUgdXBkYXRlZD9cbiAgICpcbiAgICogTlBNIHVwZGF0ZXMgdGhlaXIgZG93bmxvYWQgc3RhdHMgb25jZSBhIGRheS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSAxIGRheVxuICAgKi9cbiAgcmVhZG9ubHkgdXBkYXRlUGVyaW9kPzogRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIFRoZSBrZXkgb2YgdGhlIG9iamVjdCBzdG9yaW5nIHRoZSBwYWNrYWdlIHN0YXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgb2JqZWN0S2V5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBwYWNrYWdlcyB0byBwcm9jZXNzIHBlciBjaHVuay5cbiAgICpcbiAgICogQGRlZmF1bHQgMTAwXG4gICAqL1xuICByZWFkb25seSBjaHVua1NpemU/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQnVpbGRzIG9yIHJlLWJ1aWxkcyB0aGUgYHN0YXRzLmpzb25gIG9iamVjdCBpbiB0aGUgZGVzaWduYXRlZCBidWNrZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBQYWNrYWdlU3RhdHMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIHBhY2thZ2Ugc3RvcmUgYnVja2V0LCB3aGljaCBzaG91bGQgaW5jbHVkZSBib3RoIHRoZVxuICAgKiBjYXRhbG9nIGFuZCBzdGF0cy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBidWNrZXQ6IElCdWNrZXQ7XG5cbiAgLyoqXG4gICAqIFRoZSBTdGVwIEZ1bmN0aW9ucyBzdGF0ZSBtYWNoaW5lIHRoYXQgb3JjaGVzdHJhdGVzIHN0YXRzIHByb2Nlc3NpbmcuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3RhdGVNYWNoaW5lOiBzZm4uU3RhdGVNYWNoaW5lO1xuXG4gIC8qKlxuICAgKiBUaGUgTGFtYmRhIGZ1bmN0aW9ucyB1c2VkIGluIHRoZSBzdGF0ZSBtYWNoaW5lLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNodW5rZXJGdW5jdGlvbjogSUZ1bmN0aW9uO1xuICBwdWJsaWMgcmVhZG9ubHkgcHJvY2Vzc29yRnVuY3Rpb246IElGdW5jdGlvbjtcbiAgcHVibGljIHJlYWRvbmx5IGFnZ3JlZ2F0b3JGdW5jdGlvbjogSUZ1bmN0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUga2V5IG9mIHRoZSBvYmplY3Qgc3RvcmluZyB0aGUgcGFja2FnZSBzdGF0cy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzdGF0c0tleTogc3RyaW5nO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogUGFja2FnZVN0YXRzUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5idWNrZXQgPSBwcm9wcy5idWNrZXQ7XG4gICAgdGhpcy5zdGF0c0tleSA9IHByb3BzLm9iamVjdEtleTtcblxuICAgIGNvbnN0IGNvbW1vbkVudiA9IHtcbiAgICAgIENBVEFMT0dfQlVDS0VUX05BTUU6IHRoaXMuYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICBDQVRBTE9HX09CSkVDVF9LRVk6IENBVEFMT0dfS0VZLFxuICAgICAgU1RBVFNfQlVDS0VUX05BTUU6IHRoaXMuYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICBTVEFUU19PQkpFQ1RfS0VZOiBwcm9wcy5vYmplY3RLZXksXG4gICAgICBDSFVOS19TSVpFOiAocHJvcHMuY2h1bmtTaXplID8/IDEwMCkudG9TdHJpbmcoKSxcbiAgICB9O1xuXG4gICAgLy8gQ3JlYXRlIExhbWJkYSBmdW5jdGlvbnNcbiAgICB0aGlzLmNodW5rZXJGdW5jdGlvbiA9IG5ldyBQYWNrYWdlU3RhdHNDaHVua2VyKHRoaXMsICdDaHVua2VyJywge1xuICAgICAgZGVzY3JpcHRpb246ICdTcGxpdHMgcGFja2FnZSBsaXN0IGludG8gY2h1bmtzIGZvciBwYXJhbGxlbCBwcm9jZXNzaW5nJyxcbiAgICAgIGVudmlyb25tZW50OiBjb21tb25FbnYsXG4gICAgICBsb2dSZXRlbnRpb246IHByb3BzLmxvZ1JldGVudGlvbiA/PyBSZXRlbnRpb25EYXlzLlRFTl9ZRUFSUyxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICB0cmFjaW5nOiBUcmFjaW5nLlBBU1NfVEhST1VHSCxcbiAgICB9KTtcblxuICAgIHRoaXMucHJvY2Vzc29yRnVuY3Rpb24gPSBuZXcgUGFja2FnZVN0YXRzUHJvY2Vzc29yKHRoaXMsICdQcm9jZXNzb3InLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1Byb2Nlc3NlcyBhIGNodW5rIG9mIHBhY2thZ2VzIHRvIGdldCBOUE0gc3RhdHMnLFxuICAgICAgZW52aXJvbm1lbnQ6IGNvbW1vbkVudixcbiAgICAgIGxvZ1JldGVudGlvbjogcHJvcHMubG9nUmV0ZW50aW9uID8/IFJldGVudGlvbkRheXMuVEVOX1lFQVJTLFxuICAgICAgbWVtb3J5U2l6ZTogMTAyNCxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMTApLFxuICAgICAgdHJhY2luZzogVHJhY2luZy5QQVNTX1RIUk9VR0gsXG4gICAgfSk7XG5cbiAgICB0aGlzLmFnZ3JlZ2F0b3JGdW5jdGlvbiA9IG5ldyBQYWNrYWdlU3RhdHNBZ2dyZWdhdG9yKHRoaXMsICdBZ2dyZWdhdG9yJywge1xuICAgICAgZGVzY3JpcHRpb246ICdBZ2dyZWdhdGVzIHByb2Nlc3NlZCBjaHVua3MgaW50byBmaW5hbCBzdGF0cy5qc29uJyxcbiAgICAgIGVudmlyb25tZW50OiBjb21tb25FbnYsXG4gICAgICBsb2dSZXRlbnRpb246IHByb3BzLmxvZ1JldGVudGlvbiA/PyBSZXRlbnRpb25EYXlzLlRFTl9ZRUFSUyxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICB0cmFjaW5nOiBUcmFjaW5nLlBBU1NfVEhST1VHSCxcbiAgICB9KTtcblxuICAgIC8vIEdyYW50IFMzIHBlcm1pc3Npb25zXG4gICAgdGhpcy5idWNrZXQuZ3JhbnRSZWFkV3JpdGUodGhpcy5jaHVua2VyRnVuY3Rpb24pO1xuICAgIHRoaXMuYnVja2V0LmdyYW50UmVhZFdyaXRlKHRoaXMucHJvY2Vzc29yRnVuY3Rpb24pO1xuICAgIHRoaXMuYnVja2V0LmdyYW50UmVhZFdyaXRlKHRoaXMuYWdncmVnYXRvckZ1bmN0aW9uKTtcblxuICAgIC8vIENyZWF0ZSBTdGVwIEZ1bmN0aW9ucyBzdGF0ZSBtYWNoaW5lXG4gICAgY29uc3QgY2h1bmtQYWNrYWdlcyA9IG5ldyB0YXNrcy5MYW1iZGFJbnZva2UodGhpcywgJ0NodW5rUGFja2FnZXMnLCB7XG4gICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jaHVua2VyRnVuY3Rpb24sXG4gICAgICByZXN1bHRQYXRoOiAnJC5jaHVua3MnLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvY2Vzc0NodW5rc01hcCA9IG5ldyBzZm4uTWFwKHRoaXMsICdQcm9jZXNzQ2h1bmtzTWFwJywge1xuICAgICAgaXRlbXNQYXRoOiAnJC5jaHVua3MuUGF5bG9hZC5jaHVua3MnLFxuICAgICAgbWF4Q29uY3VycmVuY3k6IDEwLFxuICAgICAgcmVzdWx0UGF0aDogJyQucHJvY2Vzc1Jlc3VsdHMnLFxuICAgIH0pO1xuXG4gICAgcHJvY2Vzc0NodW5rc01hcC5pdGVtUHJvY2Vzc29yKFxuICAgICAgbmV3IHRhc2tzLkxhbWJkYUludm9rZSh0aGlzLCAnUHJvY2Vzc0NodW5rJywge1xuICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5wcm9jZXNzb3JGdW5jdGlvbixcbiAgICAgICAgaW5wdXRQYXRoOiAnJCcsXG4gICAgICB9KVxuICAgICAgICAuYWRkUmV0cnkoe1xuICAgICAgICAgIGVycm9yczogWydTdGF0ZXMuQUxMJ10sXG4gICAgICAgICAgbWF4QXR0ZW1wdHM6IDEsXG4gICAgICAgICAgYmFja29mZlJhdGU6IDEsXG4gICAgICAgICAgaW50ZXJ2YWw6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgIH0pXG4gICAgICAgIC5hZGRDYXRjaChcbiAgICAgICAgICBuZXcgc2ZuLlBhc3ModGhpcywgJ1Byb2Nlc3NDaHVua0Vycm9yJywge1xuICAgICAgICAgICAgcmVzdWx0OiBzZm4uUmVzdWx0LmZyb21PYmplY3QoeyBlcnJvcjogJ0ZhaWxlZCB0byBwcm9jZXNzIGNodW5rJyB9KSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXN1bHRQYXRoOiAnJC5lcnJvcicsXG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgKTtcblxuICAgIGNvbnN0IGFnZ3JlZ2F0ZVJlc3VsdHMgPSBuZXcgdGFza3MuTGFtYmRhSW52b2tlKHRoaXMsICdBZ2dyZWdhdGVSZXN1bHRzJywge1xuICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuYWdncmVnYXRvckZ1bmN0aW9uLFxuICAgICAgaW5wdXRQYXRoOiAnJCcsXG4gICAgfSk7XG5cbiAgICBjb25zdCBkZWZpbml0aW9uID0gY2h1bmtQYWNrYWdlc1xuICAgICAgLm5leHQocHJvY2Vzc0NodW5rc01hcClcbiAgICAgIC5uZXh0KGFnZ3JlZ2F0ZVJlc3VsdHMpO1xuXG4gICAgdGhpcy5zdGF0ZU1hY2hpbmUgPSBuZXcgc2ZuLlN0YXRlTWFjaGluZSh0aGlzLCAnU3RhdGVNYWNoaW5lJywge1xuICAgICAgZGVmaW5pdGlvbixcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLmhvdXJzKDYpLFxuICAgIH0pO1xuXG4gICAgLy8gU2NoZWR1bGUgdGhlIHN0YXRlIG1hY2hpbmVcbiAgICBjb25zdCB1cGRhdGVQZXJpb2QgPSBwcm9wcy51cGRhdGVQZXJpb2QgPz8gRHVyYXRpb24uZGF5cygxKTtcbiAgICBjb25zdCBydWxlID0gbmV3IGV2ZW50cy5SdWxlKHRoaXMsICdSdWxlJywge1xuICAgICAgc2NoZWR1bGU6IGV2ZW50cy5TY2hlZHVsZS5yYXRlKHVwZGF0ZVBlcmlvZCksXG4gICAgfSk7XG4gICAgcnVsZS5hZGRUYXJnZXQobmV3IHRhcmdldHMuU2ZuU3RhdGVNYWNoaW5lKHRoaXMuc3RhdGVNYWNoaW5lKSk7XG5cbiAgICAvLyBDcmVhdGUgYWxhcm1zXG4gICAgY29uc3QgZmFpbHVyZUFsYXJtID0gdGhpcy5zdGF0ZU1hY2hpbmVcbiAgICAgIC5tZXRyaWNGYWlsZWQoKVxuICAgICAgLmNyZWF0ZUFsYXJtKHNjb3BlLCAnUGFja2FnZVN0YXRzL0ZhaWx1cmVzJywge1xuICAgICAgICBhbGFybU5hbWU6IGAke3Njb3BlLm5vZGUucGF0aH0vUGFja2FnZVN0YXRzL0ZhaWx1cmVzYCxcbiAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjogW1xuICAgICAgICAgICdUaGUgcGFja2FnZSBzdGF0cyBzdGF0ZSBtYWNoaW5lIGZhaWxlZCEnLFxuICAgICAgICAgICcnLFxuICAgICAgICAgIGBSdW5Cb29rOiAke1JVTkJPT0tfVVJMfWAsXG4gICAgICAgIF0uam9pbignXFxuJyksXG4gICAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjpcbiAgICAgICAgICBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HLFxuICAgICAgfSk7XG4gICAgcHJvcHMubW9uaXRvcmluZy5hZGRMb3dTZXZlcml0eUFsYXJtKCdQYWNrYWdlU3RhdHMgRmFpbHVyZXMnLCBmYWlsdXJlQWxhcm0pO1xuICB9XG5cbiAgcHVibGljIG1ldHJpY1BhY2thZ2VzQ291bnQob3B0cz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiBuZXcgTWV0cmljKHtcbiAgICAgIHBlcmlvZDogRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgIHN0YXRpc3RpYzogU3RhdGlzdGljLk1BWElNVU0sXG4gICAgICAuLi5vcHRzLFxuICAgICAgbWV0cmljTmFtZTogTWV0cmljTmFtZS5SRUdJU1RFUkVEX1BBQ0tBR0VTX1dJVEhfU1RBVFMsXG4gICAgICBuYW1lc3BhY2U6IE1FVFJJQ1NfTkFNRVNQQUNFLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,7 @@
1
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
2
+ import { Construct } from 'constructs';
3
+ export interface PackageStatsAggregatorProps extends lambda.FunctionOptions {
4
+ }
5
+ export declare class PackageStatsAggregator extends lambda.Function {
6
+ constructor(scope: Construct, id: string, props?: PackageStatsAggregatorProps);
7
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PackageStatsAggregator = void 0;
4
+ // ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen".
5
+ const path = require("path");
6
+ const lambda = require("aws-cdk-lib/aws-lambda");
7
+ class PackageStatsAggregator extends lambda.Function {
8
+ constructor(scope, id, props) {
9
+ super(scope, id, {
10
+ description: 'backend/package-stats/package-stats-aggregator.lambda.ts',
11
+ ...props,
12
+ architecture: lambda.Architecture.ARM_64,
13
+ runtime: lambda.Runtime.NODEJS_22_X,
14
+ handler: 'index.handler',
15
+ code: lambda.Code.fromAsset(path.join(__dirname, '/package-stats-aggregator.lambda.bundle')),
16
+ });
17
+ }
18
+ }
19
+ exports.PackageStatsAggregator = PackageStatsAggregator;
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS1zdGF0cy1hZ2dyZWdhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tlbmQvcGFja2FnZS1zdGF0cy9wYWNrYWdlLXN0YXRzLWFnZ3JlZ2F0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkVBQTZFO0FBQzdFLDZCQUE2QjtBQUM3QixpREFBaUQ7QUFNakQsTUFBYSxzQkFBdUIsU0FBUSxNQUFNLENBQUMsUUFBUTtJQUN6RCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW1DO1FBQzNFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsV0FBVyxFQUFFLDBEQUEwRDtZQUN2RSxHQUFHLEtBQUs7WUFDUixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNO1lBQ3hDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVc7WUFDbkMsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLHlDQUF5QyxDQUFDLENBQUM7U0FDN0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBWEQsd0RBV0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB+fiBHZW5lcmF0ZWQgYnkgcHJvamVuLiBUbyBtb2RpZnksIGVkaXQgLnByb2plbnJjLnRzIGFuZCBydW4gXCJucHggcHJvamVuXCIuXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFja2FnZVN0YXRzQWdncmVnYXRvclByb3BzIGV4dGVuZHMgbGFtYmRhLkZ1bmN0aW9uT3B0aW9ucyB7XG59XG5cbmV4cG9ydCBjbGFzcyBQYWNrYWdlU3RhdHNBZ2dyZWdhdG9yIGV4dGVuZHMgbGFtYmRhLkZ1bmN0aW9uIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBQYWNrYWdlU3RhdHNBZ2dyZWdhdG9yUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnYmFja2VuZC9wYWNrYWdlLXN0YXRzL3BhY2thZ2Utc3RhdHMtYWdncmVnYXRvci5sYW1iZGEudHMnLFxuICAgICAgLi4ucHJvcHMsXG4gICAgICBhcmNoaXRlY3R1cmU6IGxhbWJkYS5BcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgJy9wYWNrYWdlLXN0YXRzLWFnZ3JlZ2F0b3IubGFtYmRhLmJ1bmRsZScpKSxcbiAgICB9KTtcbiAgfVxufSJdfQ==