@studion/infra-code-blocks 0.7.0 → 0.8.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/components/acm-certificate.d.ts +1 -0
  2. package/dist/components/acm-certificate.d.ts.map +1 -0
  3. package/dist/components/database-replica.d.ts +1 -0
  4. package/dist/components/database-replica.d.ts.map +1 -0
  5. package/dist/components/database.d.ts +1 -0
  6. package/dist/components/database.d.ts.map +1 -0
  7. package/dist/components/ec2-ssm-connect.d.ts +1 -0
  8. package/dist/components/ec2-ssm-connect.d.ts.map +1 -0
  9. package/dist/components/ecs-service.d.ts +1 -0
  10. package/dist/components/ecs-service.d.ts.map +1 -0
  11. package/dist/components/ecs-service.js +2 -1
  12. package/dist/components/mongo.d.ts +1 -0
  13. package/dist/components/mongo.d.ts.map +1 -0
  14. package/dist/components/nuxt-ssr.d.ts +1 -0
  15. package/dist/components/nuxt-ssr.d.ts.map +1 -0
  16. package/dist/components/password.d.ts +1 -0
  17. package/dist/components/password.d.ts.map +1 -0
  18. package/dist/components/project.d.ts +1 -0
  19. package/dist/components/project.d.ts.map +1 -0
  20. package/dist/components/redis.d.ts +1 -0
  21. package/dist/components/redis.d.ts.map +1 -0
  22. package/dist/components/static-site.d.ts +1 -0
  23. package/dist/components/static-site.d.ts.map +1 -0
  24. package/dist/components/web-server.d.ts +1 -0
  25. package/dist/components/web-server.d.ts.map +1 -0
  26. package/dist/components/web-server.js +2 -1
  27. package/dist/constants.d.ts +1 -0
  28. package/dist/constants.d.ts.map +1 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +2 -0
  32. package/dist/types/pulumi.d.ts +5 -0
  33. package/dist/types/pulumi.d.ts.map +1 -0
  34. package/dist/types/pulumi.js +2 -0
  35. package/dist/types/size.d.ts +1 -0
  36. package/dist/types/size.d.ts.map +1 -0
  37. package/dist/v2/components/ecs-service/index.d.ts +156 -0
  38. package/dist/v2/components/ecs-service/index.d.ts.map +1 -0
  39. package/dist/v2/components/ecs-service/index.js +365 -0
  40. package/dist/v2/components/ecs-service/policies.d.ts +3 -0
  41. package/dist/v2/components/ecs-service/policies.d.ts.map +1 -0
  42. package/dist/v2/components/ecs-service/policies.js +16 -0
  43. package/dist/v2/components/grafana/dashboards/index.d.ts +3 -0
  44. package/dist/v2/components/grafana/dashboards/index.d.ts.map +1 -0
  45. package/dist/v2/components/grafana/dashboards/index.js +6 -0
  46. package/dist/v2/components/grafana/dashboards/panels.d.ts +6 -0
  47. package/dist/v2/components/grafana/dashboards/panels.d.ts.map +1 -0
  48. package/dist/v2/components/grafana/dashboards/panels.js +91 -0
  49. package/dist/v2/components/grafana/dashboards/types.d.ts +66 -0
  50. package/dist/v2/components/grafana/dashboards/types.d.ts.map +1 -0
  51. package/dist/v2/components/grafana/dashboards/types.js +2 -0
  52. package/dist/v2/components/grafana/dashboards/web-server-slo.d.ts +17 -0
  53. package/dist/v2/components/grafana/dashboards/web-server-slo.d.ts.map +1 -0
  54. package/dist/v2/components/grafana/dashboards/web-server-slo.js +98 -0
  55. package/dist/v2/components/grafana/index.d.ts +2 -0
  56. package/dist/v2/components/grafana/index.d.ts.map +1 -0
  57. package/dist/v2/components/grafana/index.js +4 -0
  58. package/dist/v2/components/prometheus/index.d.ts +2 -0
  59. package/dist/v2/components/prometheus/index.d.ts.map +1 -0
  60. package/dist/v2/components/prometheus/index.js +4 -0
  61. package/dist/v2/components/prometheus/queries.d.ts +10 -0
  62. package/dist/v2/components/prometheus/queries.d.ts.map +1 -0
  63. package/dist/v2/components/prometheus/queries.js +61 -0
  64. package/dist/v2/components/prometheus/queries.test.d.ts +2 -0
  65. package/dist/v2/components/prometheus/queries.test.d.ts.map +1 -0
  66. package/dist/v2/components/prometheus/queries.test.js +52 -0
  67. package/dist/v2/components/web-server/builder.d.ts +34 -0
  68. package/dist/v2/components/web-server/builder.d.ts.map +1 -0
  69. package/dist/v2/components/web-server/builder.js +72 -0
  70. package/dist/v2/components/web-server/index.d.ts +58 -0
  71. package/dist/v2/components/web-server/index.d.ts.map +1 -0
  72. package/dist/v2/components/web-server/index.js +169 -0
  73. package/dist/v2/components/web-server/load-balancer.d.ts +25 -0
  74. package/dist/v2/components/web-server/load-balancer.d.ts.map +1 -0
  75. package/dist/v2/components/web-server/load-balancer.js +106 -0
  76. package/dist/v2/index.d.ts +13 -0
  77. package/dist/v2/index.d.ts.map +1 -0
  78. package/dist/v2/index.js +16 -0
  79. package/dist/v2/otel/batch-processor.d.ts +14 -0
  80. package/dist/v2/otel/batch-processor.d.ts.map +1 -0
  81. package/dist/v2/otel/batch-processor.js +9 -0
  82. package/dist/v2/otel/builder.d.ts +27 -0
  83. package/dist/v2/otel/builder.d.ts.map +1 -0
  84. package/dist/v2/otel/builder.js +110 -0
  85. package/dist/v2/otel/config.d.ts +26 -0
  86. package/dist/v2/otel/config.d.ts.map +1 -0
  87. package/dist/v2/otel/config.js +159 -0
  88. package/dist/v2/otel/index.d.ts +94 -0
  89. package/dist/v2/otel/index.d.ts.map +1 -0
  90. package/dist/v2/otel/index.js +82 -0
  91. package/dist/v2/otel/memory-limiter-processor.d.ts +13 -0
  92. package/dist/v2/otel/memory-limiter-processor.d.ts.map +1 -0
  93. package/dist/v2/otel/memory-limiter-processor.js +8 -0
  94. package/dist/v2/otel/otlp-receiver.d.ts +19 -0
  95. package/dist/v2/otel/otlp-receiver.d.ts.map +1 -0
  96. package/dist/v2/otel/otlp-receiver.js +11 -0
  97. package/dist/v2/otel/prometheus-remote-write-exporter.d.ts +11 -0
  98. package/dist/v2/otel/prometheus-remote-write-exporter.d.ts.map +1 -0
  99. package/dist/v2/otel/prometheus-remote-write-exporter.js +2 -0
  100. package/package.json +30 -6
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const pulumi = require("@pulumi/pulumi");
4
+ const grafana = require("@pulumiverse/grafana");
5
+ const prometheus_1 = require("../../prometheus");
6
+ const panels_1 = require("./panels");
7
+ class WebServerSloDashboardBuilder {
8
+ constructor(name, args) {
9
+ this.panels = [];
10
+ this.name = name;
11
+ this.title = pulumi.output(args.title);
12
+ }
13
+ withAvailability(target, window, dataSource, prometheusNamespace) {
14
+ const availabilityPercentage = prometheus_1.queries.getAvailabilityPercentageQuery(prometheusNamespace, window);
15
+ const availabilityBurnRate = prometheus_1.queries.getBurnRateQuery(prometheus_1.queries.getAvailabilityQuery(prometheusNamespace, '1h'), target);
16
+ const availabilitySloPanel = (0, panels_1.createStatPercentagePanel)('Availability', { x: 0, y: 0, w: 8, h: 8 }, dataSource, {
17
+ label: 'Availability',
18
+ query: availabilityPercentage,
19
+ thresholds: []
20
+ });
21
+ const availabilityBurnRatePanel = (0, panels_1.createBurnRatePanel)('Availability Burn Rate', { x: 0, y: 8, w: 8, h: 4 }, dataSource, {
22
+ label: 'Burn Rate',
23
+ query: availabilityBurnRate,
24
+ thresholds: []
25
+ });
26
+ this.panels.push(availabilitySloPanel, availabilityBurnRatePanel);
27
+ return this;
28
+ }
29
+ withSuccessRate(target, window, shortWindow, filter, dataSource, prometheusNamespace) {
30
+ const successRateSlo = prometheus_1.queries.getSuccessPercentageQuery(prometheusNamespace, window, filter);
31
+ const successRateBurnRate = prometheus_1.queries.getBurnRateQuery(prometheus_1.queries.getSuccessRateQuery(prometheusNamespace, '1h', filter), target);
32
+ const successRate = prometheus_1.queries.getSuccessPercentageQuery(prometheusNamespace, shortWindow, filter);
33
+ const successRateSloPanel = (0, panels_1.createStatPercentagePanel)('Success Rate', { x: 8, y: 0, w: 8, h: 8 }, dataSource, {
34
+ label: 'Success Rate',
35
+ query: successRateSlo,
36
+ thresholds: []
37
+ });
38
+ const successRatePanel = (0, panels_1.createTimeSeriesPercentagePanel)('HTTP Request Success Rate', { x: 0, y: 16, w: 12, h: 8 }, dataSource, {
39
+ label: 'Success Rate',
40
+ query: successRate,
41
+ thresholds: []
42
+ });
43
+ const successRateBurnRatePanel = (0, panels_1.createBurnRatePanel)('Success Rate Burn Rate', { x: 8, y: 8, w: 8, h: 4 }, dataSource, {
44
+ label: 'Burn Rate',
45
+ query: successRateBurnRate,
46
+ thresholds: []
47
+ });
48
+ this.panels.push(successRateSloPanel, successRatePanel, successRateBurnRatePanel);
49
+ return this;
50
+ }
51
+ withLatency(target, targetLatency, window, shortWindow, filter, dataSource, prometheusNamespace) {
52
+ const latencySlo = prometheus_1.queries.getLatencyPercentageQuery(prometheusNamespace, window, targetLatency, filter);
53
+ const latencyBurnRate = prometheus_1.queries.getBurnRateQuery(prometheus_1.queries.getLatencyRateQuery(prometheusNamespace, '1h', targetLatency), target);
54
+ const percentileLatency = prometheus_1.queries.getPercentileLatencyQuery(prometheusNamespace, shortWindow, target, filter);
55
+ const latencyBelowThreshold = prometheus_1.queries.getLatencyPercentageQuery(prometheusNamespace, shortWindow, targetLatency, filter);
56
+ const latencySloPanel = (0, panels_1.createStatPercentagePanel)('Request % below 250ms', { x: 16, y: 0, w: 8, h: 8 }, dataSource, {
57
+ label: 'Request % below 250ms',
58
+ query: latencySlo,
59
+ thresholds: []
60
+ });
61
+ const percentileLatencyPanel = (0, panels_1.createTimeSeriesPanel)('99th Percentile Latency', { x: 12, y: 16, w: 12, h: 8 }, dataSource, {
62
+ label: '99th Percentile Latency',
63
+ query: percentileLatency,
64
+ thresholds: []
65
+ }, 'ms');
66
+ const latencyPercentagePanel = (0, panels_1.createTimeSeriesPercentagePanel)('Request percentage below 250ms', { x: 0, y: 24, w: 12, h: 8 }, dataSource, {
67
+ label: 'Request percentage below 250ms',
68
+ query: latencyBelowThreshold,
69
+ thresholds: []
70
+ });
71
+ const latencyBurnRatePanel = (0, panels_1.createBurnRatePanel)('Latency Burn Rate', { x: 16, y: 8, w: 8, h: 4 }, dataSource, {
72
+ label: 'Burn Rate',
73
+ query: latencyBurnRate,
74
+ thresholds: []
75
+ });
76
+ this.panels.push(latencySloPanel, percentileLatencyPanel, latencyPercentagePanel, latencyBurnRatePanel);
77
+ return this;
78
+ }
79
+ build(provider) {
80
+ return pulumi.all([
81
+ this.title,
82
+ this.panels,
83
+ provider,
84
+ this.tags
85
+ ]).apply(([title, panels, provider, tags]) => {
86
+ return new grafana.oss.Dashboard(this.name, {
87
+ configJson: JSON.stringify({
88
+ title,
89
+ tags,
90
+ timezone: 'browser',
91
+ refresh: '10s',
92
+ panels,
93
+ })
94
+ }, { provider });
95
+ });
96
+ }
97
+ }
98
+ exports.default = WebServerSloDashboardBuilder;
@@ -0,0 +1,2 @@
1
+ export * as dashboard from './dashboards';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/grafana/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dashboard = void 0;
4
+ exports.dashboard = require("./dashboards");
@@ -0,0 +1,2 @@
1
+ export * as queries from './queries';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/prometheus/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queries = void 0;
4
+ exports.queries = require("./queries");
@@ -0,0 +1,10 @@
1
+ export type TimeRange = '30s' | '2m' | '5m' | '1h' | '1d';
2
+ export declare function getBurnRateQuery(metricQuery: string, target: number): string;
3
+ export declare function getAvailabilityQuery(namespace: string, timeRange: TimeRange): string;
4
+ export declare function getAvailabilityPercentageQuery(namespace: string, timeRange: TimeRange): string;
5
+ export declare function getSuccessRateQuery(namespace: string, timeRange: TimeRange, filter: string): string;
6
+ export declare function getSuccessPercentageQuery(namespace: string, timeRange: TimeRange, filter: string): string;
7
+ export declare function getPercentileLatencyQuery(namespace: string, timeRange: TimeRange, percentile: number, filter: string): string;
8
+ export declare function getLatencyRateQuery(namespace: string, timeRange: TimeRange, threshold: number, filter?: string): string;
9
+ export declare function getLatencyPercentageQuery(namespace: string, timeRange: TimeRange, threshold: number, filter?: string): string;
10
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/prometheus/queries.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAO1D,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,GACnB,MAAM,CAaR;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,GACnB,MAAM,CAER;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,GACb,MAAM,CAgBR;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,MAAM,CAKR;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAWR;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAER"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBurnRateQuery = getBurnRateQuery;
4
+ exports.getAvailabilityQuery = getAvailabilityQuery;
5
+ exports.getAvailabilityPercentageQuery = getAvailabilityPercentageQuery;
6
+ exports.getSuccessRateQuery = getSuccessRateQuery;
7
+ exports.getSuccessPercentageQuery = getSuccessPercentageQuery;
8
+ exports.getPercentileLatencyQuery = getPercentileLatencyQuery;
9
+ exports.getLatencyRateQuery = getLatencyRateQuery;
10
+ exports.getLatencyPercentageQuery = getLatencyPercentageQuery;
11
+ const metricName = 'http_server_duration_milliseconds';
12
+ const countPostfix = 'count';
13
+ const bucketPostfix = 'bucket';
14
+ const httpStatusCodeLabel = 'http_status_code';
15
+ function getBurnRateQuery(metricQuery, target) {
16
+ return `(1 - ${metricQuery}) / ${(1 - target).toFixed(5)}`;
17
+ }
18
+ function getAvailabilityQuery(namespace, timeRange) {
19
+ const successFilter = `${httpStatusCodeLabel}!~"5.."`;
20
+ const successfulRequestsQuery = getCountRate(namespace, timeRange, successFilter);
21
+ const totalRequestsQuery = getCountRate(namespace, timeRange);
22
+ return `${successfulRequestsQuery} / ${totalRequestsQuery}`;
23
+ }
24
+ function getAvailabilityPercentageQuery(namespace, timeRange) {
25
+ return `${getAvailabilityQuery(namespace, timeRange)} * 100`;
26
+ }
27
+ function getSuccessRateQuery(namespace, timeRange, filter) {
28
+ const successFilter = [`${httpStatusCodeLabel}=~"[2-4].."`, filter].join(',');
29
+ const totalFilter = filter;
30
+ const successfulRequestsQuery = getCountRate(namespace, timeRange, successFilter);
31
+ const totalRequestsQuery = getCountRate(namespace, timeRange, totalFilter);
32
+ return `${successfulRequestsQuery} / ${totalRequestsQuery}`;
33
+ }
34
+ function getSuccessPercentageQuery(namespace, timeRange, filter) {
35
+ return `${getSuccessRateQuery(namespace, timeRange, filter)} * 100`;
36
+ }
37
+ function getPercentileLatencyQuery(namespace, timeRange, percentile, filter) {
38
+ const bucketMetric = getMetric(namespace, bucketPostfix, filter);
39
+ const bucketRate = `sum by(le) (rate(${bucketMetric}[${timeRange}]))`;
40
+ return `histogram_quantile(${percentile}, ${bucketRate})`;
41
+ }
42
+ function getLatencyRateQuery(namespace, timeRange, threshold, filter) {
43
+ const filterWithThreshold = [`le="${threshold}"`, filter].join(',');
44
+ const requestsUnderThreshold = getBucketRate(namespace, timeRange, filterWithThreshold);
45
+ const totalRequests = getCountRate(namespace, timeRange, filter);
46
+ return `${requestsUnderThreshold} / ${totalRequests}`;
47
+ }
48
+ function getLatencyPercentageQuery(namespace, timeRange, threshold, filter) {
49
+ return `${getLatencyRateQuery(namespace, timeRange, threshold, filter)} * 100`;
50
+ }
51
+ function getCountRate(namespace, timeRange, filter) {
52
+ const countMetric = getMetric(namespace, countPostfix, filter);
53
+ return `sum(rate(${countMetric}[${timeRange}]))`;
54
+ }
55
+ function getBucketRate(namespace, timeRange, filter) {
56
+ const bucketMetric = getMetric(namespace, bucketPostfix, filter);
57
+ return `sum(rate(${bucketMetric}[${timeRange}]))`;
58
+ }
59
+ function getMetric(namespace, postfix, filter) {
60
+ return `${namespace}_${metricName}_${postfix}${filter ? `{${filter}}` : ''}`;
61
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=queries.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.test.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/prometheus/queries.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const node_test_1 = require("node:test");
13
+ const assert = require("node:assert/strict");
14
+ const queries_1 = require("./queries");
15
+ (0, node_test_1.describe)('Prometheus Query Builders', () => __awaiter(void 0, void 0, void 0, function* () {
16
+ const namespace = 'app';
17
+ const timeRange = '2m';
18
+ const apiRouteFilter = 'http_route=~"/api/.*"';
19
+ (0, node_test_1.describe)('getAvailabilityQuery', () => __awaiter(void 0, void 0, void 0, function* () {
20
+ (0, node_test_1.it)('should build correct query', () => {
21
+ const result = (0, queries_1.getAvailabilityQuery)(namespace, timeRange);
22
+ const expected = `(sum(rate(${namespace}_http_server_duration_milliseconds_count{http_status_code!~"5.."}[${timeRange}]))) / ` +
23
+ `(sum(rate(${namespace}_http_server_duration_milliseconds_count[${timeRange}]))) * 100`;
24
+ assert.equal(result, expected);
25
+ });
26
+ }));
27
+ (0, node_test_1.describe)('getSuccessRateQuery', () => __awaiter(void 0, void 0, void 0, function* () {
28
+ (0, node_test_1.it)('should build correct query', () => {
29
+ const result = (0, queries_1.getSuccessRateQuery)(namespace, timeRange, apiRouteFilter);
30
+ const expected = `(sum(rate(${namespace}_http_server_duration_milliseconds_count{http_status_code=~"[2-4]..",${apiRouteFilter}}[2m]))) / ` +
31
+ `(sum(rate(${namespace}_http_server_duration_milliseconds_count{${apiRouteFilter}}[2m]))) * 100`;
32
+ assert.equal(result, expected);
33
+ });
34
+ }));
35
+ (0, node_test_1.describe)('getPercentileLatencyQuery', () => __awaiter(void 0, void 0, void 0, function* () {
36
+ (0, node_test_1.it)('should build correct query', () => {
37
+ const percentile = 0.95;
38
+ const result = (0, queries_1.getPercentileLatencyQuery)(namespace, timeRange, percentile, apiRouteFilter);
39
+ const expected = `histogram_quantile(${percentile}, sum by(le) (rate(${namespace}_http_server_duration_milliseconds_bucket{${apiRouteFilter}}[${timeRange}])))`;
40
+ assert.equal(result, expected);
41
+ });
42
+ }));
43
+ (0, node_test_1.describe)('getLatencyPercentageQuery', () => __awaiter(void 0, void 0, void 0, function* () {
44
+ (0, node_test_1.it)('should build correct query', () => {
45
+ const threshold = 200;
46
+ const result = (0, queries_1.getLatencyPercentageQuery)(namespace, timeRange, threshold, apiRouteFilter);
47
+ const expected = `(sum(rate(${namespace}_http_server_duration_milliseconds_bucket{le="200",${apiRouteFilter}}[2m]))) / ` +
48
+ `(sum(rate(${namespace}_http_server_duration_milliseconds_count{${apiRouteFilter}}[2m]))) * 100`;
49
+ assert.equal(result, expected);
50
+ });
51
+ }));
52
+ }));
@@ -0,0 +1,34 @@
1
+ import * as pulumi from '@pulumi/pulumi';
2
+ import * as awsx from '@pulumi/awsx';
3
+ import { EcsService } from '../ecs-service';
4
+ import { WebServer } from '.';
5
+ import { OtelCollector } from '../../otel';
6
+ export declare namespace WebServerBuilder {
7
+ type EcsConfig = Omit<WebServer.EcsConfig, 'vpc' | 'volumes'>;
8
+ type Args = Omit<WebServer.Args, 'vpc' | 'publicSubnetIds' | 'cluster' | 'volumes' | 'domain' | 'hostedZoneId' | 'otelCollectorConfig'>;
9
+ }
10
+ export declare class WebServerBuilder {
11
+ private _name;
12
+ private _container?;
13
+ private _vpc?;
14
+ private _ecsConfig?;
15
+ private _domain?;
16
+ private _hostedZoneId?;
17
+ private _healthCheckPath?;
18
+ private _otelCollector?;
19
+ private _initContainers;
20
+ private _sidecarContainers;
21
+ private _volumes;
22
+ constructor(name: string);
23
+ configureWebServer(image: WebServer.Container['image'], port: WebServer.Container['port'], config?: Omit<WebServer.Container, 'image' | 'port'>): this;
24
+ configureEcs(config: WebServerBuilder.EcsConfig): this;
25
+ withVpc(vpc: pulumi.Input<awsx.ec2.Vpc>): this;
26
+ withVolume(volume: EcsService.PersistentStorageVolume): this;
27
+ withCustomDomain(domain: pulumi.Input<string>, hostedZoneId: pulumi.Input<string>): this;
28
+ withInitContainer(container: WebServer.InitContainer): this;
29
+ withSidecarContainer(container: WebServer.SidecarContainer): this;
30
+ withOtelCollector(collector: OtelCollector): this;
31
+ withCustomHealthCheckPath(path: WebServer.Args['healthCheckPath']): this;
32
+ build(opts?: pulumi.ComponentResourceOptions): WebServer;
33
+ }
34
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/web-server/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,yBAAiB,gBAAgB,CAAC;IAChC,KAAY,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC;IAErE,KAAY,IAAI,GAAG,IAAI,CACrB,SAAS,CAAC,IAAI,EACZ,KAAK,GACL,iBAAiB,GACjB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,cAAc,GACd,qBAAqB,CACxB,CAAA;CACF;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAC,CAAsB;IACzC,OAAO,CAAC,IAAI,CAAC,CAA8B;IAC3C,OAAO,CAAC,UAAU,CAAC,CAA6B;IAChD,OAAO,CAAC,OAAO,CAAC,CAAuB;IACvC,OAAO,CAAC,aAAa,CAAC,CAAuB;IAC7C,OAAO,CAAC,gBAAgB,CAAC,CAAuB;IAChD,OAAO,CAAC,cAAc,CAAC,CAA8B;IACrD,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,kBAAkB,CAAkD;IAC5E,OAAO,CAAC,QAAQ,CAA4C;gBAEhD,IAAI,EAAE,MAAM;IAIjB,kBAAkB,CACvB,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,EACnC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,EACjC,MAAM,GAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAM,GACvD,IAAI;IAUA,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,SAAS,GAAG,IAAI;IActD,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI;IAM9C,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,uBAAuB,GAAG,IAAI;IAM5D,gBAAgB,CACrB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAC5B,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GACjC,IAAI;IAOA,iBAAiB,CAAC,SAAS,EAAE,SAAS,CAAC,aAAa,GAAG,IAAI;IAM3D,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI;IAMjE,iBAAiB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI;IAMjD,yBAAyB,CAC9B,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,GACtC,IAAI;IAMA,KAAK,CAAC,IAAI,GAAE,MAAM,CAAC,wBAA6B,GAAG,SAAS;CAyBpE"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebServerBuilder = void 0;
4
+ const pulumi = require("@pulumi/pulumi");
5
+ const _1 = require(".");
6
+ class WebServerBuilder {
7
+ constructor(name) {
8
+ this._initContainers = [];
9
+ this._sidecarContainers = [];
10
+ this._volumes = [];
11
+ this._name = name;
12
+ }
13
+ configureWebServer(image, port, config = {}) {
14
+ this._container = Object.assign({ image,
15
+ port }, config);
16
+ return this;
17
+ }
18
+ configureEcs(config) {
19
+ this._ecsConfig = {
20
+ cluster: config.cluster,
21
+ desiredCount: config.desiredCount,
22
+ autoscaling: config.autoscaling,
23
+ size: config.size,
24
+ taskExecutionRoleInlinePolicies: config.taskExecutionRoleInlinePolicies,
25
+ taskRoleInlinePolicies: config.taskRoleInlinePolicies,
26
+ tags: config.tags,
27
+ };
28
+ return this;
29
+ }
30
+ withVpc(vpc) {
31
+ this._vpc = pulumi.output(vpc);
32
+ return this;
33
+ }
34
+ withVolume(volume) {
35
+ this._volumes.push(volume);
36
+ return this;
37
+ }
38
+ withCustomDomain(domain, hostedZoneId) {
39
+ this._domain = domain;
40
+ this._hostedZoneId = hostedZoneId;
41
+ return this;
42
+ }
43
+ withInitContainer(container) {
44
+ this._initContainers.push(container);
45
+ return this;
46
+ }
47
+ withSidecarContainer(container) {
48
+ this._sidecarContainers.push(container);
49
+ return this;
50
+ }
51
+ withOtelCollector(collector) {
52
+ this._otelCollector = collector;
53
+ return this;
54
+ }
55
+ withCustomHealthCheckPath(path) {
56
+ this._healthCheckPath = path;
57
+ return this;
58
+ }
59
+ build(opts = {}) {
60
+ if (!this._container) {
61
+ throw new Error('Web server not configured. Make sure to call WebServerBuilder.configureWebServer().');
62
+ }
63
+ if (!this._ecsConfig) {
64
+ throw new Error('ECS not configured. Make sure to call WebServerBuilder.configureEcs().');
65
+ }
66
+ if (!this._vpc) {
67
+ throw new Error('VPC not provided. Make sure to call WebServerBuilder.withVpc().');
68
+ }
69
+ return new _1.WebServer(this._name, Object.assign(Object.assign(Object.assign({}, this._ecsConfig), this._container), { vpc: this._vpc, volumes: this._volumes, publicSubnetIds: this._vpc.publicSubnetIds, domain: this._domain, hostedZoneId: this._hostedZoneId, healthCheckPath: this._healthCheckPath, otelCollector: this._otelCollector, initContainers: this._initContainers, sidecarContainers: this._sidecarContainers }), opts);
70
+ }
71
+ }
72
+ exports.WebServerBuilder = WebServerBuilder;
@@ -0,0 +1,58 @@
1
+ import * as pulumi from '@pulumi/pulumi';
2
+ import * as aws from '@pulumi/aws';
3
+ import { AcmCertificate } from '../../../components/acm-certificate';
4
+ import { EcsService } from '../ecs-service';
5
+ import { WebServerLoadBalancer } from './load-balancer';
6
+ import { OtelCollector } from '../../otel';
7
+ export declare namespace WebServer {
8
+ type Container = Pick<EcsService.Container, 'image' | 'environment' | 'secrets' | 'mountPoints'> & {
9
+ port: pulumi.Input<number>;
10
+ };
11
+ type EcsConfig = Pick<EcsService.Args, 'cluster' | 'vpc' | 'volumes' | 'desiredCount' | 'autoscaling' | 'size' | 'taskExecutionRoleInlinePolicies' | 'taskRoleInlinePolicies' | 'tags'>;
12
+ type InitContainer = Omit<EcsService.Container, 'essential'>;
13
+ type SidecarContainer = Omit<EcsService.Container, 'essential' | 'healthCheck'> & Required<Pick<EcsService.Container, 'healthCheck'>>;
14
+ type Args = EcsConfig & Container & {
15
+ publicSubnetIds: pulumi.Input<pulumi.Input<string>[]>;
16
+ /**
17
+ * The domain which will be used to access the service.
18
+ * The domain or subdomain must belong to the provided hostedZone.
19
+ */
20
+ domain?: pulumi.Input<string>;
21
+ hostedZoneId?: pulumi.Input<string>;
22
+ /**
23
+ * Path for the load balancer target group health check request.
24
+ *
25
+ * @default
26
+ * "/healthcheck"
27
+ */
28
+ healthCheckPath?: pulumi.Input<string>;
29
+ initContainers?: pulumi.Input<pulumi.Input<WebServer.InitContainer>[]>;
30
+ sidecarContainers?: pulumi.Input<pulumi.Input<WebServer.SidecarContainer>[]>;
31
+ otelCollector?: pulumi.Input<OtelCollector>;
32
+ };
33
+ }
34
+ export declare class WebServer extends pulumi.ComponentResource {
35
+ name: string;
36
+ container: WebServer.Container;
37
+ ecsConfig: WebServer.EcsConfig;
38
+ service: pulumi.Output<EcsService>;
39
+ serviceSecurityGroup: aws.ec2.SecurityGroup;
40
+ lb: WebServerLoadBalancer;
41
+ initContainers?: pulumi.Output<EcsService.Container[]>;
42
+ sidecarContainers?: pulumi.Output<EcsService.Container[]>;
43
+ volumes?: pulumi.Output<EcsService.PersistentStorageVolume[]>;
44
+ certificate?: AcmCertificate;
45
+ dnsRecord?: aws.route53.Record;
46
+ constructor(name: string, args: WebServer.Args, opts?: pulumi.ComponentResourceOptions);
47
+ private getVolumes;
48
+ private getInitContainers;
49
+ private getSidecarContainers;
50
+ private getTaskRoleInlinePolicies;
51
+ private createEcsConfig;
52
+ private createWebServerContainer;
53
+ private createTlsCertificate;
54
+ private createSecurityGroup;
55
+ private createEcsService;
56
+ private createDnsRecord;
57
+ }
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/web-server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebServer = void 0;
4
+ const pulumi = require("@pulumi/pulumi");
5
+ const aws = require("@pulumi/aws");
6
+ const constants_1 = require("../../../constants");
7
+ const acm_certificate_1 = require("../../../components/acm-certificate");
8
+ const ecs_service_1 = require("../ecs-service");
9
+ const load_balancer_1 = require("./load-balancer");
10
+ class WebServer extends pulumi.ComponentResource {
11
+ constructor(name, args, opts = {}) {
12
+ var _a;
13
+ super('studion:WebServer', name, args, opts);
14
+ const { vpc, domain, hostedZoneId } = args;
15
+ if (domain && !hostedZoneId) {
16
+ throw new Error('WebServer:hostedZoneId must be provided when the domain is specified');
17
+ }
18
+ const hasCustomDomain = !!domain && !!hostedZoneId;
19
+ if (hasCustomDomain) {
20
+ this.certificate = this.createTlsCertificate({ domain, hostedZoneId });
21
+ }
22
+ this.name = name;
23
+ this.lb = new load_balancer_1.WebServerLoadBalancer(`${this.name}-lb`, {
24
+ vpc,
25
+ port: args.port,
26
+ certificate: (_a = this.certificate) === null || _a === void 0 ? void 0 : _a.certificate,
27
+ healthCheckPath: args.healthCheckPath
28
+ });
29
+ this.serviceSecurityGroup = this.createSecurityGroup(vpc);
30
+ this.initContainers = this.getInitContainers(args);
31
+ this.sidecarContainers = this.getSidecarContainers(args);
32
+ this.container = this.createWebServerContainer(args);
33
+ this.ecsConfig = this.createEcsConfig(args);
34
+ this.volumes = this.getVolumes(args);
35
+ // TODO: Move output mapping to createEcsService
36
+ this.service = pulumi.all([
37
+ this.initContainers,
38
+ this.sidecarContainers,
39
+ ]).apply(([initContainers, sidecarContainers,]) => {
40
+ return this.createEcsService(this.container, this.lb, this.ecsConfig, this.volumes, [...initContainers, ...sidecarContainers]);
41
+ });
42
+ if (hasCustomDomain) {
43
+ this.dnsRecord = this.createDnsRecord({ domain, hostedZoneId });
44
+ }
45
+ this.registerOutputs();
46
+ }
47
+ getVolumes(args) {
48
+ return pulumi.all([
49
+ pulumi.output(args.volumes),
50
+ args.otelCollector
51
+ ]).apply(([passedVolumes, otelCollector]) => {
52
+ const volumes = [];
53
+ if (passedVolumes)
54
+ volumes.push(...passedVolumes);
55
+ if (otelCollector)
56
+ volumes.push({ name: otelCollector.configVolume });
57
+ return volumes;
58
+ });
59
+ }
60
+ getInitContainers(args) {
61
+ return pulumi.all([
62
+ pulumi.output(args.initContainers),
63
+ args.otelCollector
64
+ ]).apply(([passedInits, otelCollector]) => {
65
+ const containers = [];
66
+ if (passedInits)
67
+ containers.push(...passedInits);
68
+ if (otelCollector)
69
+ containers.push(otelCollector.configContainer);
70
+ return containers.map(container => (Object.assign(Object.assign({}, container), { essential: false })));
71
+ });
72
+ }
73
+ getSidecarContainers(args) {
74
+ return pulumi.all([
75
+ pulumi.output(args.sidecarContainers),
76
+ args.otelCollector
77
+ ]).apply(([passedSidecars, otelCollector]) => {
78
+ const containers = [];
79
+ if (passedSidecars)
80
+ containers.push(...passedSidecars);
81
+ if (otelCollector)
82
+ containers.push(otelCollector.container);
83
+ return containers.map(container => (Object.assign(Object.assign({}, container), { essential: true })));
84
+ });
85
+ }
86
+ getTaskRoleInlinePolicies(args) {
87
+ return pulumi.all([
88
+ pulumi.output(args.taskExecutionRoleInlinePolicies),
89
+ args.otelCollector
90
+ ]).apply(([passedTaskRoleInlinePolicies, otelCollector]) => {
91
+ const inlinePolicies = [];
92
+ if (passedTaskRoleInlinePolicies)
93
+ inlinePolicies.push(...passedTaskRoleInlinePolicies);
94
+ if (otelCollector && otelCollector.taskRoleInlinePolicies) {
95
+ inlinePolicies.push(...otelCollector.taskRoleInlinePolicies);
96
+ }
97
+ return inlinePolicies;
98
+ });
99
+ }
100
+ createEcsConfig(args) {
101
+ return {
102
+ vpc: args.vpc,
103
+ cluster: args.cluster,
104
+ desiredCount: args.desiredCount,
105
+ autoscaling: args.autoscaling,
106
+ size: args.size,
107
+ taskExecutionRoleInlinePolicies: args.taskExecutionRoleInlinePolicies,
108
+ taskRoleInlinePolicies: this.getTaskRoleInlinePolicies(args),
109
+ tags: args.tags,
110
+ };
111
+ }
112
+ createWebServerContainer(args) {
113
+ return {
114
+ image: args.image,
115
+ mountPoints: args.mountPoints,
116
+ environment: args.environment,
117
+ secrets: args.secrets,
118
+ port: args.port
119
+ };
120
+ }
121
+ createTlsCertificate({ domain, hostedZoneId, }) {
122
+ return new acm_certificate_1.AcmCertificate(`${domain}-acm-certificate`, {
123
+ domain,
124
+ hostedZoneId,
125
+ }, { parent: this });
126
+ }
127
+ createSecurityGroup(vpc) {
128
+ const vpcId = pulumi.output(vpc).vpcId;
129
+ return new aws.ec2.SecurityGroup(`${this.name}-security-group`, {
130
+ vpcId,
131
+ ingress: [{
132
+ fromPort: 0,
133
+ toPort: 0,
134
+ protocol: '-1',
135
+ securityGroups: [this.lb.securityGroup.id],
136
+ }],
137
+ egress: [{
138
+ fromPort: 0,
139
+ toPort: 0,
140
+ protocol: '-1',
141
+ cidrBlocks: ['0.0.0.0/0'],
142
+ }],
143
+ tags: constants_1.commonTags,
144
+ }, { parent: this });
145
+ }
146
+ createEcsService(webServerContainer, lb, ecsConfig, volumes, containers) {
147
+ return new ecs_service_1.EcsService(`${this.name}-ecs`, Object.assign(Object.assign({}, ecsConfig), { volumes, containers: [Object.assign(Object.assign({}, webServerContainer), { name: this.name, portMappings: [ecs_service_1.EcsService.createTcpPortMapping(webServerContainer.port)], essential: true }), ...(containers || [])], enableServiceAutoDiscovery: false, loadBalancers: [{
148
+ containerName: this.name,
149
+ containerPort: webServerContainer.port,
150
+ targetGroupArn: lb.targetGroup.arn,
151
+ }], assignPublicIp: true, securityGroup: this.serviceSecurityGroup }), {
152
+ parent: this,
153
+ dependsOn: [lb, lb.targetGroup],
154
+ });
155
+ }
156
+ createDnsRecord({ domain, hostedZoneId, }) {
157
+ return new aws.route53.Record(`${this.name}-route53-record`, {
158
+ type: 'A',
159
+ name: domain,
160
+ zoneId: hostedZoneId,
161
+ aliases: [{
162
+ name: this.lb.lb.dnsName,
163
+ zoneId: this.lb.lb.zoneId,
164
+ evaluateTargetHealth: true,
165
+ }],
166
+ }, { parent: this });
167
+ }
168
+ }
169
+ exports.WebServer = WebServer;
@@ -0,0 +1,25 @@
1
+ import * as pulumi from '@pulumi/pulumi';
2
+ import * as aws from '@pulumi/aws';
3
+ import * as awsx from '@pulumi/awsx';
4
+ export declare namespace WebServerLoadBalancer {
5
+ type Args = {
6
+ vpc: pulumi.Input<awsx.ec2.Vpc>;
7
+ port: pulumi.Input<number>;
8
+ certificate?: aws.acm.Certificate;
9
+ healthCheckPath?: pulumi.Input<string>;
10
+ };
11
+ }
12
+ export declare class WebServerLoadBalancer extends pulumi.ComponentResource {
13
+ name: string;
14
+ lb: aws.lb.LoadBalancer;
15
+ targetGroup: aws.lb.TargetGroup;
16
+ httpListener: aws.lb.Listener;
17
+ tlsListener: aws.lb.Listener | undefined;
18
+ securityGroup: aws.ec2.SecurityGroup;
19
+ constructor(name: string, args: WebServerLoadBalancer.Args, opts?: pulumi.ComponentResourceOptions);
20
+ private createLbTlsListener;
21
+ private createLbHttpListener;
22
+ private createLbTargetGroup;
23
+ private createLbSecurityGroup;
24
+ }
25
+ //# sourceMappingURL=load-balancer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-balancer.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/web-server/load-balancer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AAGrC,yBAAiB,qBAAqB,CAAC;IACrC,KAAY,IAAI,GAAG;QACjB,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3B,WAAW,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC;QAClC,eAAe,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;KACxC,CAAC;CACH;AA0BD,qBAAa,qBAAsB,SAAQ,MAAM,CAAC,iBAAiB;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC;IACxB,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC;IAChC,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC;IAC9B,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC;IACzC,aAAa,EAAE,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC;gBAGnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,qBAAqB,CAAC,IAAI,EAChC,IAAI,GAAE,MAAM,CAAC,wBAA6B;IAoC5C,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,oBAAoB;IA0B5B,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,qBAAqB;CAS9B"}