@stacksjs/ts-cloud 0.7.109 → 0.7.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aws/index.js +3 -3
- package/dist/bin/cli.js +938 -930
- package/dist/bin/dashboard-server.js +255 -247
- package/dist/{chunk-grx1rp09.js → chunk-19bs955w.js} +56 -16
- package/dist/{chunk-cktwk9hy.js → chunk-3ee2jav4.js} +8 -8
- package/dist/{chunk-x6yzgv7y.js → chunk-6a1t7fnq.js} +2 -2
- package/dist/{chunk-xrtwv3v2.js → chunk-d48vtdj4.js} +14 -1
- package/dist/{chunk-9v2pwxv9.js → chunk-kpeb5rcs.js} +2 -2
- package/dist/{chunk-hpv68b4a.js → chunk-nsgqsmrh.js} +1 -1
- package/dist/{chunk-wj3s95p9.js → chunk-rds0sy87.js} +3 -2
- package/dist/{chunk-k114qwg9.js → chunk-ttz2ra5j.js} +2 -2
- package/dist/{chunk-8kh577qh.js → chunk-v0vpamnf.js} +3 -3
- package/dist/{chunk-d3vx2ekv.js → chunk-wh1y5rtk.js} +5 -2
- package/dist/deploy/index.js +7 -7
- package/dist/drivers/index.js +2 -2
- package/dist/index.js +8 -8
- package/dist/protection/controls.d.ts +14 -0
- package/dist/protection/index.js +3 -1
- package/dist/spend/index.js +1 -1
- package/dist/spend/signals.d.ts +21 -0
- package/dist/ui/access-denied.html +2 -2
- package/dist/ui/account/automation.html +3 -3
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +4 -4
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +3 -3
- package/dist/ui/data/services.html +4 -4
- package/dist/ui/data/volumes.html +4 -4
- package/dist/ui/index.html +4 -4
- package/dist/ui/infrastructure/topology.html +4 -4
- package/dist/ui/operations/alerts.html +4 -4
- package/dist/ui/operations/configuration.html +4 -4
- package/dist/ui/operations/jobs.html +3 -3
- package/dist/ui/operations/maintenance.html +4 -4
- package/dist/ui/operations/observability.html +4 -4
- package/dist/ui/operations/previews.html +4 -4
- package/dist/ui/operations/queue.html +4 -4
- package/dist/ui/operations/regions.html +3 -3
- package/dist/ui/operations/releases.html +4 -4
- package/dist/ui/operations/spend.html +4 -4
- package/dist/ui/operations/workloads.html +3 -3
- package/dist/ui/security.html +2 -2
- package/dist/ui/server/actions.html +4 -4
- package/dist/ui/server/activity.html +2 -2
- package/dist/ui/server/capacity.html +4 -4
- package/dist/ui/server/database.html +4 -4
- package/dist/ui/server/deployments.html +4 -4
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +3 -3
- package/dist/ui/server/fleet.html +4 -4
- package/dist/ui/server/logs.html +3 -3
- package/dist/ui/server/metrics.html +4 -4
- package/dist/ui/server/security.html +2 -2
- package/dist/ui/server/services.html +2 -2
- package/dist/ui/server/sites.html +3 -3
- package/dist/ui/server/ssh-keys.html +4 -4
- package/dist/ui/server/team.html +3 -3
- package/dist/ui/server/terminal.html +2 -2
- package/dist/ui/serverless/alarms.html +4 -4
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/data.html +4 -4
- package/dist/ui/serverless/deployments.html +2 -2
- package/dist/ui/serverless/functions.html +4 -4
- package/dist/ui/serverless/logs.html +4 -4
- package/dist/ui/serverless/metrics.html +2 -2
- package/dist/ui/serverless/queues.html +4 -4
- package/dist/ui/serverless/secrets.html +4 -4
- package/dist/ui/serverless/traces.html +4 -4
- package/dist/ui/serverless.html +4 -4
- package/package.json +3 -3
|
@@ -462,7 +462,7 @@ function aggregateDeltas(deltas) {
|
|
|
462
462
|
import { createHash as createHash3 } from "node:crypto";
|
|
463
463
|
|
|
464
464
|
// src/control-plane/migrations.ts
|
|
465
|
-
var CONTROL_PLANE_SCHEMA_VERSION =
|
|
465
|
+
var CONTROL_PLANE_SCHEMA_VERSION = 40;
|
|
466
466
|
var controlPlaneMigrations = [
|
|
467
467
|
{
|
|
468
468
|
version: 1,
|
|
@@ -2126,6 +2126,20 @@ var controlPlaneMigrations = [
|
|
|
2126
2126
|
DROP TABLE notification_channels;
|
|
2127
2127
|
ALTER TABLE notification_channels_new RENAME TO notification_channels;
|
|
2128
2128
|
`
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
version: 40,
|
|
2132
|
+
name: "telemetry_kind_scope_index",
|
|
2133
|
+
sql: `
|
|
2134
|
+
-- Anomaly detection filters request records by (project, kind, time).
|
|
2135
|
+
-- The existing scope index leads with project_id and environment_id but
|
|
2136
|
+
-- never mentions kind, so every request series scanned each project's
|
|
2137
|
+
-- logs, metrics, and traces too and discarded them in memory. On a
|
|
2138
|
+
-- project emitting mostly logs that is several times the necessary work,
|
|
2139
|
+
-- once a minute, forever.
|
|
2140
|
+
CREATE INDEX telemetry_kind_scope_time_idx
|
|
2141
|
+
ON telemetry_records(project_id, kind, timestamp);
|
|
2142
|
+
`
|
|
2129
2143
|
}
|
|
2130
2144
|
];
|
|
2131
2145
|
// src/control-plane/store.ts
|
|
@@ -5016,21 +5030,23 @@ class AnomalyConfigStore {
|
|
|
5016
5030
|
}
|
|
5017
5031
|
// src/spend/signals.ts
|
|
5018
5032
|
var DETECTABLE_SIGNALS = [
|
|
5019
|
-
{ key: "cost", label: "Cost", source: "usage", gapPolicy: "zero", minSamples: 0, unit: "cents" },
|
|
5020
|
-
{ key: "edge.requests", label: "Edge requests", source: "usage", gapPolicy: "zero", minSamples: 0, unit: "requests" },
|
|
5021
|
-
{ key: "edge.egress_gb", label: "Edge egress", source: "usage", gapPolicy: "zero", minSamples: 0, unit: "GB" },
|
|
5033
|
+
{ key: "cost", routeAware: false, label: "Cost", source: "usage", gapPolicy: "zero", minSamples: 0, unit: "cents" },
|
|
5034
|
+
{ key: "edge.requests", routeAware: false, label: "Edge requests", source: "usage", gapPolicy: "zero", minSamples: 0, unit: "requests" },
|
|
5035
|
+
{ key: "edge.egress_gb", routeAware: false, label: "Edge egress", source: "usage", gapPolicy: "zero", minSamples: 0, unit: "GB" },
|
|
5022
5036
|
{
|
|
5023
5037
|
key: "function.invocations",
|
|
5038
|
+
routeAware: false,
|
|
5024
5039
|
label: "Function invocations",
|
|
5025
5040
|
source: "usage",
|
|
5026
5041
|
gapPolicy: "zero",
|
|
5027
5042
|
minSamples: 0,
|
|
5028
5043
|
unit: "invocations"
|
|
5029
5044
|
},
|
|
5030
|
-
{ key: "http.requests", label: "HTTP requests", source: "telemetry", gapPolicy: "zero", minSamples: 0, unit: "requests" },
|
|
5031
|
-
{ key: "http.errors", label: "HTTP 5xx", source: "telemetry", gapPolicy: "zero", minSamples: 0, unit: "responses" },
|
|
5045
|
+
{ key: "http.requests", routeAware: true, label: "HTTP requests", source: "telemetry", gapPolicy: "zero", minSamples: 0, unit: "requests" },
|
|
5046
|
+
{ key: "http.errors", routeAware: true, label: "HTTP 5xx", source: "telemetry", gapPolicy: "zero", minSamples: 0, unit: "responses" },
|
|
5032
5047
|
{
|
|
5033
5048
|
key: "http.error_rate",
|
|
5049
|
+
routeAware: true,
|
|
5034
5050
|
label: "HTTP error rate",
|
|
5035
5051
|
source: "telemetry",
|
|
5036
5052
|
gapPolicy: "gap",
|
|
@@ -5040,6 +5056,7 @@ var DETECTABLE_SIGNALS = [
|
|
|
5040
5056
|
},
|
|
5041
5057
|
{
|
|
5042
5058
|
key: "http.client_error_rate",
|
|
5059
|
+
routeAware: true,
|
|
5043
5060
|
label: "HTTP 4xx rate",
|
|
5044
5061
|
source: "telemetry",
|
|
5045
5062
|
gapPolicy: "gap",
|
|
@@ -5049,6 +5066,7 @@ var DETECTABLE_SIGNALS = [
|
|
|
5049
5066
|
},
|
|
5050
5067
|
{
|
|
5051
5068
|
key: "http.latency_p95",
|
|
5069
|
+
routeAware: true,
|
|
5052
5070
|
label: "Latency p95",
|
|
5053
5071
|
source: "telemetry",
|
|
5054
5072
|
gapPolicy: "gap",
|
|
@@ -5093,6 +5111,7 @@ function assemble(definition, window, values) {
|
|
|
5093
5111
|
class SignalSource {
|
|
5094
5112
|
controlPlane;
|
|
5095
5113
|
spend;
|
|
5114
|
+
counterCache = new Map;
|
|
5096
5115
|
constructor(controlPlane, spend) {
|
|
5097
5116
|
this.controlPlane = controlPlane;
|
|
5098
5117
|
this.spend = spend;
|
|
@@ -5117,10 +5136,8 @@ class SignalSource {
|
|
|
5117
5136
|
});
|
|
5118
5137
|
return assemble(definition, window, values);
|
|
5119
5138
|
}
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
return { signal: definition.key, points: [], populated: 0, suppressed: 0, unit: definition.unit };
|
|
5123
|
-
const clauses = ["kind = 'request'", "project_id = ?", "timestamp >= ?", "timestamp < ?"];
|
|
5139
|
+
requestFilter(scope, window) {
|
|
5140
|
+
const clauses = ["project_id = ?", "kind = 'request'", "timestamp >= ?", "timestamp < ?"];
|
|
5124
5141
|
const bindings = [scope.projectId, window.from, window.to];
|
|
5125
5142
|
if (scope.environmentId) {
|
|
5126
5143
|
clauses.push("environment_id = ?");
|
|
@@ -5130,16 +5147,35 @@ class SignalSource {
|
|
|
5130
5147
|
clauses.push("path_template = ?");
|
|
5131
5148
|
bindings.push(scope.route);
|
|
5132
5149
|
}
|
|
5150
|
+
return { clauses, bindings };
|
|
5151
|
+
}
|
|
5152
|
+
counters(scope, window) {
|
|
5153
|
+
const key = [scope.projectId, scope.environmentId ?? "", scope.route ?? "", window.from, window.to].join("\x00");
|
|
5154
|
+
const cached = this.counterCache.get(key);
|
|
5155
|
+
if (cached)
|
|
5156
|
+
return cached;
|
|
5157
|
+
const { clauses, bindings } = this.requestFilter(scope, window);
|
|
5133
5158
|
const rows = this.query(`SELECT
|
|
5134
5159
|
CAST(strftime('%s', timestamp) AS INTEGER) / 3600 AS bucket,
|
|
5135
5160
|
COUNT(*) AS total,
|
|
5136
5161
|
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS server_errors,
|
|
5137
|
-
SUM(CASE WHEN status_code >= 400 AND status_code < 500 THEN 1 ELSE 0 END) AS client_errors
|
|
5138
|
-
SUM(CASE WHEN duration_ms IS NOT NULL THEN 1 ELSE 0 END) AS timed
|
|
5162
|
+
SUM(CASE WHEN status_code >= 400 AND status_code < 500 THEN 1 ELSE 0 END) AS client_errors
|
|
5139
5163
|
FROM telemetry_records
|
|
5140
5164
|
WHERE ${clauses.join(" AND ")}
|
|
5141
5165
|
GROUP BY bucket
|
|
5142
5166
|
ORDER BY bucket`, bindings);
|
|
5167
|
+
this.counterCache.set(key, rows);
|
|
5168
|
+
return rows;
|
|
5169
|
+
}
|
|
5170
|
+
resetCache() {
|
|
5171
|
+
this.counterCache.clear();
|
|
5172
|
+
}
|
|
5173
|
+
telemetrySeries(definition, scope, window) {
|
|
5174
|
+
if (!scope.projectId)
|
|
5175
|
+
return { signal: definition.key, points: [], populated: 0, suppressed: 0, unit: definition.unit };
|
|
5176
|
+
if (definition.key === "http.latency_p95")
|
|
5177
|
+
return this.latencySeries(definition, scope, window);
|
|
5178
|
+
const rows = this.counters(scope, window);
|
|
5143
5179
|
const values = new Map;
|
|
5144
5180
|
for (const row of rows) {
|
|
5145
5181
|
const bucket = Number(row.bucket) * HOUR;
|
|
@@ -5153,11 +5189,10 @@ class SignalSource {
|
|
|
5153
5189
|
else if (definition.key === "http.client_error_rate")
|
|
5154
5190
|
values.set(bucket, { value: total > 0 ? Number(row.client_errors) / total : 0, samples: total });
|
|
5155
5191
|
}
|
|
5156
|
-
if (definition.key === "http.latency_p95")
|
|
5157
|
-
return this.latencySeries(definition, clauses, bindings, window);
|
|
5158
5192
|
return assemble(definition, window, values);
|
|
5159
5193
|
}
|
|
5160
|
-
latencySeries(definition,
|
|
5194
|
+
latencySeries(definition, scope, window) {
|
|
5195
|
+
const { clauses, bindings } = this.requestFilter(scope, window);
|
|
5161
5196
|
const rows = this.query(`WITH ranked AS (
|
|
5162
5197
|
SELECT
|
|
5163
5198
|
CAST(strftime('%s', timestamp) AS INTEGER) / 3600 AS bucket,
|
|
@@ -5415,18 +5450,23 @@ class SpendService {
|
|
|
5415
5450
|
};
|
|
5416
5451
|
const wanted = options.signals ?? DETECTABLE_SIGNALS.map((signal) => signal.key);
|
|
5417
5452
|
const found = [];
|
|
5453
|
+
let routes;
|
|
5418
5454
|
for (const signal of wanted) {
|
|
5419
5455
|
const hours = overrides.seasonLength ? Math.max(24 * 14, overrides.seasonLength * ((overrides.minHistory ?? 3) + 1)) : lookbackHoursForSignal(signal);
|
|
5420
5456
|
const window = { from: new Date(new Date(to).getTime() - hours * 3600000).toISOString(), to };
|
|
5421
5457
|
found.push(...this.detectSignal(signal, scope, window, overrides));
|
|
5422
5458
|
if (!options.routes)
|
|
5423
5459
|
continue;
|
|
5424
|
-
|
|
5460
|
+
if (!signalDefinition(signal)?.routeAware)
|
|
5461
|
+
continue;
|
|
5462
|
+
routes ??= this.signals.busiestRoutes(scope, window);
|
|
5463
|
+
for (const route of routes) {
|
|
5425
5464
|
if (this.anomalyConfigs.isSilenced(scope, { signal, route }))
|
|
5426
5465
|
continue;
|
|
5427
5466
|
found.push(...this.detectSignal(signal, { ...scope, route }, window, overrides, route));
|
|
5428
5467
|
}
|
|
5429
5468
|
}
|
|
5469
|
+
this.signals.resetCache();
|
|
5430
5470
|
return found;
|
|
5431
5471
|
}
|
|
5432
5472
|
detectSignal(signal, scope, window, overrides, route) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deployStaticSiteWithExternalDnsFull
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-v0vpamnf.js";
|
|
4
4
|
import {
|
|
5
5
|
box,
|
|
6
6
|
error,
|
|
@@ -22,10 +22,10 @@ import {
|
|
|
22
22
|
SQSClient,
|
|
23
23
|
STSClient,
|
|
24
24
|
SecretsManagerClient
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-6a1t7fnq.js";
|
|
26
26
|
import {
|
|
27
27
|
IAMClient
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-nsgqsmrh.js";
|
|
29
29
|
import {
|
|
30
30
|
CloudFrontClient
|
|
31
31
|
} from "./chunk-01d86gt1.js";
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
resolveSiteKind,
|
|
51
51
|
resolveUiSource,
|
|
52
52
|
siteInstallBase
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-wh1y5rtk.js";
|
|
54
54
|
import {
|
|
55
55
|
SSMClient
|
|
56
56
|
} from "./chunk-7m60qnc8.js";
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
import {
|
|
61
61
|
S3Client,
|
|
62
62
|
resolveCredentials
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-rds0sy87.js";
|
|
64
64
|
import {
|
|
65
65
|
AWSClient,
|
|
66
66
|
buildQueryParams
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
spendOpenApiPaths,
|
|
105
105
|
telemetryCursor,
|
|
106
106
|
telemetryEstimatedMonthlyCost
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-19bs955w.js";
|
|
108
108
|
import {
|
|
109
109
|
artifactKey,
|
|
110
110
|
buildCloudFormationTemplate,
|
|
@@ -10395,7 +10395,7 @@ async function sendAuthenticationEmail(config, message) {
|
|
|
10395
10395
|
if (!from)
|
|
10396
10396
|
return false;
|
|
10397
10397
|
try {
|
|
10398
|
-
const { EmailClient } = await import("./chunk-
|
|
10398
|
+
const { EmailClient } = await import("./chunk-ttz2ra5j.js");
|
|
10399
10399
|
const email = new EmailClient({ region: config.project.region, defaultFrom: from });
|
|
10400
10400
|
await email.send(message);
|
|
10401
10401
|
return true;
|
|
@@ -36403,7 +36403,7 @@ async function startLocalDashboardServer(options = {}) {
|
|
|
36403
36403
|
});
|
|
36404
36404
|
const notificationRouter = new NotificationRouter(alertStore, {
|
|
36405
36405
|
emailImpl: async (input) => {
|
|
36406
|
-
const { email } = await import("./chunk-
|
|
36406
|
+
const { email } = await import("./chunk-ttz2ra5j.js");
|
|
36407
36407
|
return email.send(input);
|
|
36408
36408
|
}
|
|
36409
36409
|
});
|
|
@@ -417,4 +417,17 @@ function applyControlsToDdos(config, controls) {
|
|
|
417
417
|
}
|
|
418
418
|
};
|
|
419
419
|
}
|
|
420
|
-
|
|
420
|
+
function mergeControlsIntoConfig(config, controls) {
|
|
421
|
+
const compute = config?.infrastructure?.compute;
|
|
422
|
+
if (!compute || compute.ddos === false)
|
|
423
|
+
return config;
|
|
424
|
+
const base = typeof compute.ddos === "object" && compute.ddos !== null ? compute.ddos : {};
|
|
425
|
+
return {
|
|
426
|
+
...config,
|
|
427
|
+
infrastructure: {
|
|
428
|
+
...config.infrastructure,
|
|
429
|
+
compute: { ...compute, ddos: applyControlsToDdos(base, controls) }
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
export { RATE_LIMIT_KEY_SEPARATOR, globMatches, ruleMatches, rateLimitKey, RateLimiter, rateLimitHeaders, defaultRateLimitRules, PROTECTION_SETTING, MAX_CONTROL_HOURS, DEFAULT_ATTACK_MODE_HOURS, ProtectionControlStore, describePosture, applyControlsToRateLimits, applyControlsToDdos, mergeControlsIntoConfig };
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
generateStaticSiteTemplate,
|
|
6
6
|
invalidateCache,
|
|
7
7
|
uploadStaticFiles
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-v0vpamnf.js";
|
|
9
9
|
import"./chunk-01d86gt1.js";
|
|
10
10
|
import"./chunk-gttvakpv.js";
|
|
11
11
|
import"./chunk-32e7ya18.js";
|
|
12
12
|
import"./chunk-4cjrg98a.js";
|
|
13
|
-
import"./chunk-
|
|
13
|
+
import"./chunk-rds0sy87.js";
|
|
14
14
|
import"./chunk-zqtpg06c.js";
|
|
15
15
|
import"./chunk-v0bahtg2.js";
|
|
16
16
|
export {
|
|
@@ -1407,7 +1407,8 @@ host:${host}
|
|
|
1407
1407
|
queryParams: { uploads: "" },
|
|
1408
1408
|
headers
|
|
1409
1409
|
});
|
|
1410
|
-
|
|
1410
|
+
const root = result?.InitiateMultipartUploadResult ?? result;
|
|
1411
|
+
return { UploadId: root?.UploadId };
|
|
1411
1412
|
}
|
|
1412
1413
|
async uploadPart(bucket, key, uploadId, partNumber, body) {
|
|
1413
1414
|
const { accessKeyId, secretAccessKey, sessionToken } = this.getCredentials();
|
|
@@ -1504,7 +1505,7 @@ host:${host}
|
|
|
1504
1505
|
bucket,
|
|
1505
1506
|
queryParams: { uploads: "" }
|
|
1506
1507
|
});
|
|
1507
|
-
const uploads = result?.ListMultipartUploadsResult?.Upload;
|
|
1508
|
+
const uploads = (result?.ListMultipartUploadsResult ?? result)?.Upload;
|
|
1508
1509
|
if (!uploads)
|
|
1509
1510
|
return [];
|
|
1510
1511
|
const list = Array.isArray(uploads) ? uploads : [uploads];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EmailClient,
|
|
3
3
|
email
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-nsgqsmrh.js";
|
|
5
5
|
import"./chunk-32e7ya18.js";
|
|
6
|
-
import"./chunk-
|
|
6
|
+
import"./chunk-rds0sy87.js";
|
|
7
7
|
import"./chunk-zqtpg06c.js";
|
|
8
8
|
import"./chunk-v0bahtg2.js";
|
|
9
9
|
export {
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "./chunk-4cjrg98a.js";
|
|
17
17
|
import {
|
|
18
18
|
S3Client
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-rds0sy87.js";
|
|
20
20
|
import {
|
|
21
21
|
__require
|
|
22
22
|
} from "./chunk-v0bahtg2.js";
|
|
@@ -815,7 +815,7 @@ async function deployStaticSiteWithExternalDnsFull(config) {
|
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
817
|
onProgress?.("upload", "Uploading files to S3...");
|
|
818
|
-
const { uploadStaticFiles } = await import("./chunk-
|
|
818
|
+
const { uploadStaticFiles } = await import("./chunk-kpeb5rcs.js");
|
|
819
819
|
const uploadResult = await uploadStaticFiles({
|
|
820
820
|
sourceDir,
|
|
821
821
|
bucket: infraResult.bucket,
|
|
@@ -835,7 +835,7 @@ async function deployStaticSiteWithExternalDnsFull(config) {
|
|
|
835
835
|
}
|
|
836
836
|
if (infraResult.distributionId && uploadResult.uploaded > 0) {
|
|
837
837
|
onProgress?.("invalidate", "Invalidating CloudFront cache...");
|
|
838
|
-
const { invalidateCache } = await import("./chunk-
|
|
838
|
+
const { invalidateCache } = await import("./chunk-kpeb5rcs.js");
|
|
839
839
|
await invalidateCache(infraResult.distributionId);
|
|
840
840
|
}
|
|
841
841
|
onProgress?.("complete", "Deployment complete!");
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-4cjrg98a.js";
|
|
8
8
|
import {
|
|
9
9
|
S3Client
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-rds0sy87.js";
|
|
11
11
|
import {
|
|
12
12
|
renderWafInstallScript
|
|
13
13
|
} from "./chunk-va2yd85b.js";
|
|
@@ -1287,7 +1287,7 @@ async function sendNotifications(config, event, message, options = {}) {
|
|
|
1287
1287
|
}
|
|
1288
1288
|
async function sendEmailNotification(email, event, message) {
|
|
1289
1289
|
try {
|
|
1290
|
-
const mod = await import("./chunk-
|
|
1290
|
+
const mod = await import("./chunk-ttz2ra5j.js");
|
|
1291
1291
|
await mod.email.send({
|
|
1292
1292
|
to: email.to,
|
|
1293
1293
|
from: email.from,
|
|
@@ -1877,6 +1877,9 @@ function buildRpxProvisionScript(options) {
|
|
|
1877
1877
|
"OOMPolicy=stop",
|
|
1878
1878
|
"Restart=always",
|
|
1879
1879
|
"RestartSec=5",
|
|
1880
|
+
"StartLimitIntervalSec=120",
|
|
1881
|
+
"StartLimitBurst=5",
|
|
1882
|
+
`ExecStartPre=/bin/sh -c 'for p in 80 443; do fuser -k -n tcp "$p" 2>/dev/null || true; done; sleep 1'`,
|
|
1880
1883
|
"LimitNOFILE=1048576",
|
|
1881
1884
|
"AmbientCapabilities=CAP_NET_BIND_SERVICE",
|
|
1882
1885
|
"",
|
package/dist/deploy/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
synchronizeDashboardUsers,
|
|
37
37
|
trackDashboardOperation,
|
|
38
38
|
verifyStaticApiOrigin
|
|
39
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-3ee2jav4.js";
|
|
40
40
|
import {
|
|
41
41
|
deleteStaticSite,
|
|
42
42
|
deployStaticSite,
|
|
@@ -47,12 +47,12 @@ import {
|
|
|
47
47
|
generateStaticSiteTemplate,
|
|
48
48
|
invalidateCache,
|
|
49
49
|
uploadStaticFiles
|
|
50
|
-
} from "../chunk-
|
|
50
|
+
} from "../chunk-v0vpamnf.js";
|
|
51
51
|
import {
|
|
52
52
|
buildAndPushServerlessImage
|
|
53
53
|
} from "../chunk-wmbep3b5.js";
|
|
54
|
-
import"../chunk-
|
|
55
|
-
import"../chunk-
|
|
54
|
+
import"../chunk-6a1t7fnq.js";
|
|
55
|
+
import"../chunk-nsgqsmrh.js";
|
|
56
56
|
import"../chunk-01d86gt1.js";
|
|
57
57
|
import"../chunk-50jpda9q.js";
|
|
58
58
|
import"../chunk-he9a874b.js";
|
|
@@ -78,12 +78,12 @@ import {
|
|
|
78
78
|
siteInstallBase,
|
|
79
79
|
validateDeploymentConfig,
|
|
80
80
|
verifyAddressRecord
|
|
81
|
-
} from "../chunk-
|
|
81
|
+
} from "../chunk-wh1y5rtk.js";
|
|
82
82
|
import"../chunk-7m60qnc8.js";
|
|
83
83
|
import"../chunk-4cjrg98a.js";
|
|
84
|
-
import"../chunk-
|
|
84
|
+
import"../chunk-rds0sy87.js";
|
|
85
85
|
import"../chunk-zqtpg06c.js";
|
|
86
|
-
import"../chunk-
|
|
86
|
+
import"../chunk-19bs955w.js";
|
|
87
87
|
import"../chunk-va2yd85b.js";
|
|
88
88
|
import"../chunk-aa2dkn7b.js";
|
|
89
89
|
import"../chunk-t2s3gdq6.js";
|
package/dist/drivers/index.js
CHANGED
|
@@ -68,10 +68,10 @@ import {
|
|
|
68
68
|
waitForSsh,
|
|
69
69
|
wrapCloudInitUserData,
|
|
70
70
|
writeResizeCheckpoint
|
|
71
|
-
} from "../chunk-
|
|
71
|
+
} from "../chunk-wh1y5rtk.js";
|
|
72
72
|
import"../chunk-7m60qnc8.js";
|
|
73
73
|
import"../chunk-4cjrg98a.js";
|
|
74
|
-
import"../chunk-
|
|
74
|
+
import"../chunk-rds0sy87.js";
|
|
75
75
|
import"../chunk-zqtpg06c.js";
|
|
76
76
|
import"../chunk-va2yd85b.js";
|
|
77
77
|
import"../chunk-aa2dkn7b.js";
|
package/dist/index.js
CHANGED
|
@@ -208,7 +208,7 @@ import {
|
|
|
208
208
|
verifyUpdateSignature,
|
|
209
209
|
webhookEndpoint,
|
|
210
210
|
zeroCapacity
|
|
211
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-3ee2jav4.js";
|
|
212
212
|
import {
|
|
213
213
|
deleteStaticSite,
|
|
214
214
|
deployStaticSite,
|
|
@@ -219,7 +219,7 @@ import {
|
|
|
219
219
|
generateStaticSiteTemplate,
|
|
220
220
|
invalidateCache,
|
|
221
221
|
uploadStaticFiles
|
|
222
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-v0vpamnf.js";
|
|
223
223
|
import {
|
|
224
224
|
buildAndPushServerlessImage
|
|
225
225
|
} from "./chunk-wmbep3b5.js";
|
|
@@ -260,12 +260,12 @@ import {
|
|
|
260
260
|
providerEndpoint,
|
|
261
261
|
remapKey,
|
|
262
262
|
resolveObjectStorage
|
|
263
|
-
} from "./chunk-
|
|
263
|
+
} from "./chunk-6a1t7fnq.js";
|
|
264
264
|
import {
|
|
265
265
|
EmailClient,
|
|
266
266
|
IAMClient,
|
|
267
267
|
SESClient
|
|
268
|
-
} from "./chunk-
|
|
268
|
+
} from "./chunk-nsgqsmrh.js";
|
|
269
269
|
import {
|
|
270
270
|
CloudFrontClient
|
|
271
271
|
} from "./chunk-01d86gt1.js";
|
|
@@ -338,7 +338,7 @@ import {
|
|
|
338
338
|
waitForCloudInit,
|
|
339
339
|
waitForSsh,
|
|
340
340
|
wrapCloudInitUserData
|
|
341
|
-
} from "./chunk-
|
|
341
|
+
} from "./chunk-wh1y5rtk.js";
|
|
342
342
|
import {
|
|
343
343
|
EC2Client,
|
|
344
344
|
SSMClient
|
|
@@ -348,7 +348,7 @@ import {
|
|
|
348
348
|
} from "./chunk-4cjrg98a.js";
|
|
349
349
|
import {
|
|
350
350
|
S3Client
|
|
351
|
-
} from "./chunk-
|
|
351
|
+
} from "./chunk-rds0sy87.js";
|
|
352
352
|
import {
|
|
353
353
|
AWSClient
|
|
354
354
|
} from "./chunk-zqtpg06c.js";
|
|
@@ -511,7 +511,7 @@ import {
|
|
|
511
511
|
zeroFill,
|
|
512
512
|
zoneOffsetMs,
|
|
513
513
|
zonedParts
|
|
514
|
-
} from "./chunk-
|
|
514
|
+
} from "./chunk-19bs955w.js";
|
|
515
515
|
import {
|
|
516
516
|
DEFAULT_ATTACK_MODE_HOURS,
|
|
517
517
|
MAX_CONTROL_HOURS,
|
|
@@ -526,7 +526,7 @@ import {
|
|
|
526
526
|
rateLimitHeaders,
|
|
527
527
|
rateLimitKey,
|
|
528
528
|
ruleMatches
|
|
529
|
-
} from "./chunk-
|
|
529
|
+
} from "./chunk-d48vtdj4.js";
|
|
530
530
|
import {
|
|
531
531
|
escapeSecLang,
|
|
532
532
|
globToRegex,
|
|
@@ -111,3 +111,17 @@ export declare function describePosture(controls: ReturnType<ProtectionControlSt
|
|
|
111
111
|
export declare function applyControlsToRateLimits(rules: readonly RateLimitRule[], controls: ReturnType<ProtectionControlStore['current']>): RateLimitRule[];
|
|
112
112
|
/** Apply the controls to a firewall config before it is rendered. */
|
|
113
113
|
export declare function applyControlsToDdos(config: DdosConfig, controls: ReturnType<ProtectionControlStore['current']>): DdosConfig;
|
|
114
|
+
/**
|
|
115
|
+
* Fold live operator controls into a cloud config before it reaches a driver.
|
|
116
|
+
*
|
|
117
|
+
* The provisioning path takes a `CloudConfig` and nothing else, deliberately:
|
|
118
|
+
* it also builds golden images, and baking one operator's live blocklist into a
|
|
119
|
+
* reusable image would be wrong. So the merge happens here, at the deploy call
|
|
120
|
+
* site that has a control plane, rather than inside the builder.
|
|
121
|
+
*
|
|
122
|
+
* Without this, `cloud protect:block` writes a rule that the next deploy
|
|
123
|
+
* silently renders without - the control appears to work and does nothing.
|
|
124
|
+
*
|
|
125
|
+
* Returns a shallow copy; the caller's config is not mutated.
|
|
126
|
+
*/
|
|
127
|
+
export declare function mergeControlsIntoConfig<T extends Record<string, any>>(config: T, controls: ReturnType<ProtectionControlStore['current']>): T;
|
package/dist/protection/index.js
CHANGED
|
@@ -10,10 +10,11 @@ import {
|
|
|
10
10
|
defaultRateLimitRules,
|
|
11
11
|
describePosture,
|
|
12
12
|
globMatches,
|
|
13
|
+
mergeControlsIntoConfig,
|
|
13
14
|
rateLimitHeaders,
|
|
14
15
|
rateLimitKey,
|
|
15
16
|
ruleMatches
|
|
16
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-d48vtdj4.js";
|
|
17
18
|
import {
|
|
18
19
|
escapeSecLang,
|
|
19
20
|
globToRegex,
|
|
@@ -60,6 +61,7 @@ export {
|
|
|
60
61
|
propagationHeaders,
|
|
61
62
|
planMitigation,
|
|
62
63
|
parseChain,
|
|
64
|
+
mergeControlsIntoConfig,
|
|
63
65
|
isValidCidr,
|
|
64
66
|
isSafePattern,
|
|
65
67
|
inspectInvocation,
|
package/dist/spend/index.js
CHANGED
package/dist/spend/signals.d.ts
CHANGED
|
@@ -18,6 +18,15 @@ export interface SignalDefinition {
|
|
|
18
18
|
unit: string;
|
|
19
19
|
/** True when the signal is a ratio in 0-1. */
|
|
20
20
|
ratio?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* True when the signal can be narrowed to a route.
|
|
23
|
+
*
|
|
24
|
+
* Usage rollups have no route dimension: they are priced per meter, not per
|
|
25
|
+
* path. Running route detection over them produces a series that is actually
|
|
26
|
+
* project-wide and records it under a route's name, which is worse than
|
|
27
|
+
* useless - it is a confidently mislabelled anomaly.
|
|
28
|
+
*/
|
|
29
|
+
routeAware: boolean;
|
|
21
30
|
}
|
|
22
31
|
/**
|
|
23
32
|
* The signals detection can run on.
|
|
@@ -53,10 +62,22 @@ export interface SignalSeries {
|
|
|
53
62
|
export declare class SignalSource {
|
|
54
63
|
private readonly controlPlane;
|
|
55
64
|
private readonly spend;
|
|
65
|
+
private readonly counterCache;
|
|
56
66
|
constructor(controlPlane: ControlPlaneStore, spend: SpendStore);
|
|
57
67
|
private query;
|
|
58
68
|
/** Usage-backed series: cost, or one meter's quantity. */
|
|
59
69
|
private usageSeries;
|
|
70
|
+
private requestFilter;
|
|
71
|
+
/**
|
|
72
|
+
* Per-bucket request counters for a scope and window.
|
|
73
|
+
*
|
|
74
|
+
* Memoized because four signals derive from the same numbers. Computing them
|
|
75
|
+
* separately meant four full passes over the request history every cycle, and
|
|
76
|
+
* with per-route detection that multiplied by the route count.
|
|
77
|
+
*/
|
|
78
|
+
private counters;
|
|
79
|
+
/** Drop the memo so a long-lived source re-reads on the next cycle. */
|
|
80
|
+
resetCache(): void;
|
|
60
81
|
/**
|
|
61
82
|
* Telemetry-backed series, aggregated in SQL.
|
|
62
83
|
*
|