@hasna/uptime 0.1.6 → 0.1.7
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/.dockerignore +0 -1
- package/CHANGELOG.md +20 -1
- package/Dockerfile +2 -1
- package/Dockerfile.package +22 -0
- package/README.md +7 -1
- package/dist/api.js +38 -8
- package/dist/cli/index.js +91 -43
- package/dist/cloud-plan.d.ts +11 -4
- package/dist/cloud-plan.d.ts.map +1 -1
- package/dist/cloud-plan.js +43 -31
- package/dist/index.js +81 -39
- package/dist/mcp/index.js +38 -8
- package/dist/service.d.ts +1 -1
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +38 -8
- package/dist/store.d.ts +3 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +40 -9
- package/docs/aws-deployment-runbook.md +30 -20
- package/infra/aws/README.md +17 -6
- package/infra/aws/main.tf +282 -33
- package/infra/aws/outputs.tf +12 -0
- package/infra/aws/terraform.tfvars.example +10 -10
- package/infra/aws/variables.tf +25 -21
- package/package.json +2 -1
package/dist/cloud-plan.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// src/cloud-plan.ts
|
|
3
|
-
var DEFAULT_ACCOUNT = "
|
|
3
|
+
var DEFAULT_ACCOUNT = "aws-profile";
|
|
4
4
|
var DEFAULT_REGION = "us-east-1";
|
|
5
5
|
var DEFAULT_STAGE = "prod";
|
|
6
6
|
var DEFAULT_PREFIX = "open-uptime";
|
|
7
|
-
var DEFAULT_HOSTNAME = "uptime.
|
|
8
|
-
var DEFAULT_WORKSPACE_ID = "
|
|
9
|
-
var DEFAULT_VPC_ID = "vpc-
|
|
10
|
-
var
|
|
7
|
+
var DEFAULT_HOSTNAME = "uptime.example.com";
|
|
8
|
+
var DEFAULT_WORKSPACE_ID = "workspace-id";
|
|
9
|
+
var DEFAULT_VPC_ID = "vpc-xxxxxxxx";
|
|
10
|
+
var DEFAULT_HOSTED_SQLITE_DB = "/data/uptime/uptime.db";
|
|
11
11
|
function buildAwsDeploymentPlan(options = {}) {
|
|
12
12
|
const region = clean(options.region, DEFAULT_REGION);
|
|
13
13
|
const stage = clean(options.stage, DEFAULT_STAGE);
|
|
@@ -15,37 +15,39 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
15
15
|
const accountName = clean(options.accountName, DEFAULT_ACCOUNT);
|
|
16
16
|
const hostname = clean(options.hostname, DEFAULT_HOSTNAME);
|
|
17
17
|
const workspaceId = clean(options.workspaceId, DEFAULT_WORKSPACE_ID);
|
|
18
|
-
const ecrRepository = clean(options.ecrRepository,
|
|
18
|
+
const ecrRepository = clean(options.ecrRepository, prefix);
|
|
19
19
|
const imageRepositoryUri = `<account-id>.dkr.ecr.${region}.amazonaws.com/${ecrRepository}`;
|
|
20
20
|
const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
|
|
21
21
|
const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
|
|
22
|
+
const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
|
|
23
|
+
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.7");
|
|
22
24
|
const cluster = `${prefix}-${stage}`;
|
|
23
25
|
const secrets = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
reporting: clean(options.reportingSecretName, `hasna/xyz/opensource/uptime/${stage}/reporting`)
|
|
26
|
+
appEnv: clean(options.appEnvSecretName, `open-uptime/${stage}/app/env`),
|
|
27
|
+
hostedToken: clean(options.hostedTokenSecretName, `open-uptime/${stage}/hosted-token`),
|
|
28
|
+
publicProbe: clean(options.publicProbeSecretName, `open-uptime/${stage}/probe/public`),
|
|
29
|
+
privateProbe: clean(options.privateProbeSecretName, `open-uptime/${stage}/probe/private`),
|
|
30
|
+
reporting: clean(options.reportingSecretName, `open-uptime/${stage}/reporting`)
|
|
30
31
|
};
|
|
31
32
|
const services = [
|
|
32
|
-
servicePlan(prefix, stage, "web",
|
|
33
|
+
servicePlan(prefix, stage, "web", 1, image, workspaceId, secrets, {
|
|
33
34
|
HASNA_UPTIME_MODE: "hosted",
|
|
35
|
+
HASNA_UPTIME_HOSTED_SQLITE_DB: hostedSqliteDbPath,
|
|
34
36
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
35
37
|
HASNA_UPTIME_HOSTNAME: hostname
|
|
36
38
|
}),
|
|
37
|
-
servicePlan(prefix, stage, "scheduler",
|
|
39
|
+
servicePlan(prefix, stage, "scheduler", 0, image, workspaceId, secrets, {
|
|
38
40
|
HASNA_UPTIME_MODE: "hosted",
|
|
39
41
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
40
42
|
HASNA_UPTIME_COMPONENT: "scheduler"
|
|
41
43
|
}),
|
|
42
|
-
servicePlan(prefix, stage, "public-probe",
|
|
44
|
+
servicePlan(prefix, stage, "public-probe", 0, image, workspaceId, secrets, {
|
|
43
45
|
HASNA_UPTIME_MODE: "hosted",
|
|
44
46
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
45
47
|
HASNA_UPTIME_COMPONENT: "public-probe",
|
|
46
48
|
HASNA_UPTIME_PROBE_LOCATION: region
|
|
47
49
|
}),
|
|
48
|
-
servicePlan(prefix, stage, "reporter",
|
|
50
|
+
servicePlan(prefix, stage, "reporter", 0, image, workspaceId, secrets, {
|
|
49
51
|
HASNA_UPTIME_MODE: "hosted",
|
|
50
52
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
51
53
|
HASNA_UPTIME_COMPONENT: "reporter"
|
|
@@ -58,7 +60,7 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
58
60
|
];
|
|
59
61
|
return {
|
|
60
62
|
kind: "open-uptime.aws-deployment-plan",
|
|
61
|
-
version:
|
|
63
|
+
version: 2,
|
|
62
64
|
generatedAt: new Date().toISOString(),
|
|
63
65
|
status: "blocked",
|
|
64
66
|
canApply: false,
|
|
@@ -71,10 +73,13 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
71
73
|
mode: "hosted",
|
|
72
74
|
resources: {
|
|
73
75
|
ecrRepository,
|
|
76
|
+
imageBuilder: `${prefix}-${stage}-image-builder`,
|
|
74
77
|
ecsCluster: cluster,
|
|
75
78
|
services,
|
|
76
79
|
vpcId: clean(options.vpcId, DEFAULT_VPC_ID),
|
|
77
|
-
|
|
80
|
+
efsFileSystem: `${prefix}-${stage}-data`,
|
|
81
|
+
efsAccessPoint: `${prefix}-${stage}-uptime`,
|
|
82
|
+
hostedSqliteDbPath,
|
|
78
83
|
evidenceBucket,
|
|
79
84
|
loadBalancer: `${prefix}-${stage}-alb`,
|
|
80
85
|
targetGroups: [`${prefix}-${stage}-web-tg`],
|
|
@@ -84,7 +89,8 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
84
89
|
`${prefix}-${stage}-scheduler-sg`,
|
|
85
90
|
`${prefix}-${stage}-public-probe-sg`,
|
|
86
91
|
`${prefix}-${stage}-reporter-sg`,
|
|
87
|
-
`${prefix}-${stage}-migration-sg
|
|
92
|
+
`${prefix}-${stage}-migration-sg`,
|
|
93
|
+
`${prefix}-${stage}-efs-sg`
|
|
88
94
|
],
|
|
89
95
|
secrets,
|
|
90
96
|
logGroups: services.map((service) => service.logGroup),
|
|
@@ -96,10 +102,10 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
96
102
|
image: {
|
|
97
103
|
repository: ecrRepository,
|
|
98
104
|
uri: image,
|
|
99
|
-
dockerfile: "Dockerfile",
|
|
100
|
-
buildCommand: `
|
|
105
|
+
dockerfile: "Dockerfile.package",
|
|
106
|
+
buildCommand: `BLOCKED: after infra approval, AWS CodeBuild builds Dockerfile.package from @hasna/uptime@${runtimePackageVersion} into ${imageRepositoryUri}`,
|
|
101
107
|
pushCommands: [
|
|
102
|
-
|
|
108
|
+
`BLOCKED: start ${prefix}-${stage}-image-builder only through the approved deploy pipeline after @hasna/uptime@${runtimePackageVersion} is published`,
|
|
103
109
|
"BLOCKED: deploy services by immutable image digest, not by mutable tags"
|
|
104
110
|
]
|
|
105
111
|
},
|
|
@@ -114,19 +120,22 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
114
120
|
runbook: {
|
|
115
121
|
preflight: [
|
|
116
122
|
`aws sts get-caller-identity --profile ${accountName}`,
|
|
117
|
-
`aws rds describe-db-instances --db-instance-identifier ${clean(options.rdsInstanceId, DEFAULT_RDS)} --region ${region}`,
|
|
118
123
|
`aws ec2 describe-vpcs --vpc-ids ${clean(options.vpcId, DEFAULT_VPC_ID)} --region ${region}`,
|
|
124
|
+
`aws efs describe-file-systems --region ${region}`,
|
|
119
125
|
"Confirm the infra repository and Terraform/CloudFormation owner before live mutation."
|
|
120
126
|
],
|
|
121
127
|
provision: [
|
|
122
128
|
`Infra PR must declare or update ECR repository ${ecrRepository}.`,
|
|
129
|
+
`Infra PR must declare CodeBuild image builder ${prefix}-${stage}-image-builder for @hasna/uptime@${runtimePackageVersion}.`,
|
|
123
130
|
`Infra PR must declare hardened S3 evidence bucket ${evidenceBucket} with KMS, versioning, lifecycle, and public access block.`,
|
|
131
|
+
`Infra PR must declare encrypted EFS ${prefix}-${stage}-data with access point, mount targets, and AWS Backup plan.`,
|
|
124
132
|
`Infra PR must declare ECS/Fargate cluster ${cluster}, ALB, target groups, security groups, IAM roles, CloudWatch log groups, and Secrets Manager refs.`,
|
|
125
133
|
"Only apply the infra plan from the approved infrastructure repository after review evidence is attached."
|
|
126
134
|
],
|
|
127
135
|
deploy: [
|
|
128
136
|
"Build and publish the image only after the Dockerfile/container target is reviewed.",
|
|
129
|
-
|
|
137
|
+
`Start the AWS image builder for @hasna/uptime@${runtimePackageVersion} and record the pushed image digest.`,
|
|
138
|
+
"For the EFS SQLite bridge, do not run migration, scheduler, public-probe, or reporter tasks; keep them at desired count 0 until Postgres and cloud leases exist.",
|
|
130
139
|
`Register task definitions for ${services.map((service) => service.name).join(", ")} using valueFrom secrets.`,
|
|
131
140
|
`Update ECS services in cluster ${cluster} one component at a time through the approved deploy pipeline.`,
|
|
132
141
|
`Create Route53/edge record for ${hostname} only after ALB health checks pass and auth denial smokes succeed.`
|
|
@@ -135,7 +144,7 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
135
144
|
"Keep previous task definition ARNs before each service update.",
|
|
136
145
|
"Rollback through the approved deploy pipeline to the previously recorded task definition ARNs.",
|
|
137
146
|
"Disable scheduler/reporter services before data rollback.",
|
|
138
|
-
"Restore
|
|
147
|
+
"Restore EFS backup recovery point only after explicit operator approval and audit record."
|
|
139
148
|
],
|
|
140
149
|
spark01: [
|
|
141
150
|
"Create a private probe identity with a caller-managed public key.",
|
|
@@ -144,18 +153,19 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
144
153
|
]
|
|
145
154
|
},
|
|
146
155
|
blockers: [
|
|
147
|
-
"The
|
|
148
|
-
"
|
|
156
|
+
"The infrastructure owner repository was not found in this workspace.",
|
|
157
|
+
"The EFS SQLite bridge is single-writer only: web target desired count is 1 and scheduler/public-probe/reporter targets remain 0 until Postgres and cloud leases exist.",
|
|
149
158
|
"Hosted production auth/RBAC must replace broad static hosted-token operation before exposure.",
|
|
150
159
|
"Public probe execution still needs DNS, redirect, and rebinding SSRF enforcement plus cloud check-job leases.",
|
|
151
160
|
"Spark01 hosted probe enrollment, claim, submit, heartbeat, revocation, and rotation are not cloud-backed yet."
|
|
152
161
|
],
|
|
153
162
|
requiredEvidence: [
|
|
154
163
|
"Infrastructure PR/synth/plan from the approved infra repository.",
|
|
155
|
-
"
|
|
164
|
+
"CodeBuild image-builder run, container smoke, and immutable image digest.",
|
|
156
165
|
"ECS task definitions using secrets.valueFrom only.",
|
|
157
166
|
"ALB/TLS/DNS/auth denial smokes and web alarm checks.",
|
|
158
|
-
"
|
|
167
|
+
"Single-writer ECS evidence: one web task maximum and no scheduler/public-probe/reporter EFS mounts.",
|
|
168
|
+
"EFS encryption, access point, mount-target, AWS Backup, and restore-drill evidence.",
|
|
159
169
|
"S3 bucket KMS, versioning, lifecycle, and public-access-block evidence.",
|
|
160
170
|
"Spark01 private-probe registration, key-file mode, heartbeat, and revocation evidence."
|
|
161
171
|
],
|
|
@@ -165,7 +175,9 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
165
175
|
hostedLocalSqliteAllowed: false,
|
|
166
176
|
notes: [
|
|
167
177
|
"This plan generator does not call AWS.",
|
|
168
|
-
"
|
|
178
|
+
"Blocked plan output intentionally avoids copy-pastable AWS mutation commands.",
|
|
179
|
+
"Hosted runtime uses explicit EFS-backed SQLite at HASNA_UPTIME_HOSTED_SQLITE_DB until the async Postgres adapter exists.",
|
|
180
|
+
"Do not set HASNA_UPTIME_DATABASE_URL for hosted tasks until the Postgres adapter is implemented.",
|
|
169
181
|
"Secrets are represented as secret names/refs and must be injected with valueFrom.",
|
|
170
182
|
"Actual deploy belongs in the deploy_release_operate_final goal node after infra review."
|
|
171
183
|
]
|
|
@@ -257,7 +269,7 @@ function servicePlan(prefix, stage, role, desiredCount, image, workspaceId, secr
|
|
|
257
269
|
HASNA_UPTIME_IMAGE: image,
|
|
258
270
|
...environment
|
|
259
271
|
},
|
|
260
|
-
secrets: role === "web" ? {
|
|
272
|
+
secrets: role === "web" ? { APP_ENV: secrets.appEnv, HASNA_UPTIME_HOSTED_TOKEN: secrets.hostedToken } : role === "public-probe" ? { PROBE_CONFIG: secrets.publicProbe } : role === "reporter" ? { REPORTING_CONFIG: secrets.reporting } : { APP_ENV: secrets.appEnv }
|
|
261
273
|
};
|
|
262
274
|
}
|
|
263
275
|
function clean(value, fallback) {
|
package/dist/index.js
CHANGED
|
@@ -820,10 +820,12 @@ function ensureUptimeHome() {
|
|
|
820
820
|
}
|
|
821
821
|
|
|
822
822
|
// src/store.ts
|
|
823
|
-
import { copyFileSync, existsSync, mkdirSync as mkdirSync2, statSync } from "fs";
|
|
823
|
+
import { copyFileSync, existsSync, mkdirSync as mkdirSync2, statfsSync, statSync } from "fs";
|
|
824
824
|
import { dirname, join as join2 } from "path";
|
|
825
825
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
826
826
|
import { Database } from "bun:sqlite";
|
|
827
|
+
var DEFAULT_HOSTED_SQLITE_DB_PATH = "/data/uptime/uptime.db";
|
|
828
|
+
var NFS_SUPER_MAGIC = 26985;
|
|
827
829
|
var SECRET_URL_PARAM_PATTERN = /(token|secret|password|passwd|api[_-]?key|access[_-]?token|auth|credential|session)/i;
|
|
828
830
|
var REQUIRED_TABLES = [
|
|
829
831
|
"schema_migrations",
|
|
@@ -860,18 +862,39 @@ class UptimeStore {
|
|
|
860
862
|
this.mode = resolveRuntimeMode(options.mode ?? "local");
|
|
861
863
|
const cloudDatabaseUrl = options.cloudDatabaseUrl ?? process.env.HASNA_UPTIME_DATABASE_URL;
|
|
862
864
|
if (this.mode === "hosted" && cloudDatabaseUrl) {
|
|
863
|
-
throw new Error("hosted
|
|
865
|
+
throw new Error("hosted Postgres adapter is not implemented yet; use HASNA_UPTIME_HOSTED_SQLITE_DB on cloud-mounted storage for the current hosted deployment path");
|
|
864
866
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
+
const hostedSqliteDbPath = options.hostedSqliteDbPath ?? process.env.HASNA_UPTIME_HOSTED_SQLITE_DB;
|
|
868
|
+
if (this.mode === "hosted" && hostedSqliteDbPath) {
|
|
869
|
+
if (hostedSqliteDbPath === ":memory:" || !hostedSqliteDbPath.startsWith("/")) {
|
|
870
|
+
throw new Error("HASNA_UPTIME_HOSTED_SQLITE_DB must be an absolute path on mounted cloud storage");
|
|
871
|
+
}
|
|
872
|
+
const approvedHostedPath = hostedSqliteDbPath === DEFAULT_HOSTED_SQLITE_DB_PATH;
|
|
873
|
+
if (!approvedHostedPath && !allowHostedLocalStore(options.allowHostedLocalStore)) {
|
|
874
|
+
throw new Error(`HASNA_UPTIME_HOSTED_SQLITE_DB must be ${DEFAULT_HOSTED_SQLITE_DB_PATH}; set HASNA_UPTIME_ALLOW_HOSTED_LOCAL_STORE=1 only for explicit local fallback testing`);
|
|
875
|
+
}
|
|
876
|
+
const verifiedCloudMount = approvedHostedPath && isNfsMount(dirname(hostedSqliteDbPath));
|
|
877
|
+
if (approvedHostedPath && !verifiedCloudMount && !allowHostedLocalStore(options.allowHostedLocalStore)) {
|
|
878
|
+
throw new Error(`${DEFAULT_HOSTED_SQLITE_DB_PATH} must be on a mounted EFS/NFS filesystem; refusing to create hosted task-local SQLite`);
|
|
879
|
+
}
|
|
880
|
+
this.dataMode = verifiedCloudMount ? "hosted-efs-sqlite" : "hosted-local-sqlite";
|
|
881
|
+
this.dbPath = hostedSqliteDbPath;
|
|
882
|
+
} else if (this.mode === "hosted") {
|
|
883
|
+
if (!allowHostedLocalStore(options.allowHostedLocalStore)) {
|
|
884
|
+
throw new Error("hosted mode requires HASNA_UPTIME_HOSTED_SQLITE_DB on mounted cloud storage; set HASNA_UPTIME_ALLOW_HOSTED_LOCAL_STORE=1 only for explicit local fallback testing");
|
|
885
|
+
}
|
|
886
|
+
this.dataMode = "hosted-local-sqlite";
|
|
887
|
+
this.dbPath = options.dbPath ?? uptimeHostedFallbackDbPath();
|
|
888
|
+
} else {
|
|
889
|
+
this.dataMode = "local-sqlite";
|
|
890
|
+
this.dbPath = options.dbPath ?? uptimeDbPath();
|
|
867
891
|
}
|
|
868
|
-
|
|
869
|
-
this.dbPath = options.dbPath ?? (this.mode === "hosted" ? uptimeHostedFallbackDbPath() : uptimeDbPath());
|
|
870
|
-
if (this.dbPath !== ":memory:") {
|
|
892
|
+
if (this.dbPath !== ":memory:" && this.dataMode !== "hosted-efs-sqlite") {
|
|
871
893
|
mkdirSync2(dirname(this.dbPath), { recursive: true });
|
|
872
894
|
}
|
|
873
895
|
this.db = new Database(this.dbPath, { create: true });
|
|
874
|
-
this.db.run("PRAGMA journal_mode = WAL");
|
|
896
|
+
this.db.run(this.dataMode === "hosted-efs-sqlite" ? "PRAGMA journal_mode = DELETE" : "PRAGMA journal_mode = WAL");
|
|
897
|
+
this.db.run("PRAGMA busy_timeout = 5000");
|
|
875
898
|
this.db.run("PRAGMA foreign_keys = ON");
|
|
876
899
|
this.migrate();
|
|
877
900
|
}
|
|
@@ -1751,6 +1774,13 @@ function resolveRuntimeMode(mode) {
|
|
|
1751
1774
|
function allowHostedLocalStore(value) {
|
|
1752
1775
|
return value === true || process.env.HASNA_UPTIME_ALLOW_HOSTED_LOCAL_STORE === "1";
|
|
1753
1776
|
}
|
|
1777
|
+
function isNfsMount(path) {
|
|
1778
|
+
try {
|
|
1779
|
+
return statfsSync(path).type === NFS_SUPER_MAGIC;
|
|
1780
|
+
} catch {
|
|
1781
|
+
return false;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1754
1784
|
function verifyBackupFile(backupPath) {
|
|
1755
1785
|
const db = new Database(backupPath, { readonly: true });
|
|
1756
1786
|
try {
|
|
@@ -3791,14 +3821,14 @@ class ApiError extends Error {
|
|
|
3791
3821
|
}
|
|
3792
3822
|
|
|
3793
3823
|
// src/cloud-plan.ts
|
|
3794
|
-
var DEFAULT_ACCOUNT = "
|
|
3824
|
+
var DEFAULT_ACCOUNT = "aws-profile";
|
|
3795
3825
|
var DEFAULT_REGION = "us-east-1";
|
|
3796
3826
|
var DEFAULT_STAGE = "prod";
|
|
3797
3827
|
var DEFAULT_PREFIX = "open-uptime";
|
|
3798
|
-
var DEFAULT_HOSTNAME = "uptime.
|
|
3799
|
-
var DEFAULT_WORKSPACE_ID = "
|
|
3800
|
-
var DEFAULT_VPC_ID = "vpc-
|
|
3801
|
-
var
|
|
3828
|
+
var DEFAULT_HOSTNAME = "uptime.example.com";
|
|
3829
|
+
var DEFAULT_WORKSPACE_ID = "workspace-id";
|
|
3830
|
+
var DEFAULT_VPC_ID = "vpc-xxxxxxxx";
|
|
3831
|
+
var DEFAULT_HOSTED_SQLITE_DB = "/data/uptime/uptime.db";
|
|
3802
3832
|
function buildAwsDeploymentPlan(options = {}) {
|
|
3803
3833
|
const region = clean(options.region, DEFAULT_REGION);
|
|
3804
3834
|
const stage = clean(options.stage, DEFAULT_STAGE);
|
|
@@ -3806,37 +3836,39 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3806
3836
|
const accountName = clean(options.accountName, DEFAULT_ACCOUNT);
|
|
3807
3837
|
const hostname = clean(options.hostname, DEFAULT_HOSTNAME);
|
|
3808
3838
|
const workspaceId = clean(options.workspaceId, DEFAULT_WORKSPACE_ID);
|
|
3809
|
-
const ecrRepository = clean(options.ecrRepository,
|
|
3839
|
+
const ecrRepository = clean(options.ecrRepository, prefix);
|
|
3810
3840
|
const imageRepositoryUri = `<account-id>.dkr.ecr.${region}.amazonaws.com/${ecrRepository}`;
|
|
3811
3841
|
const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
|
|
3812
3842
|
const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
|
|
3843
|
+
const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
|
|
3844
|
+
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.7");
|
|
3813
3845
|
const cluster = `${prefix}-${stage}`;
|
|
3814
3846
|
const secrets = {
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
reporting: clean(options.reportingSecretName, `hasna/xyz/opensource/uptime/${stage}/reporting`)
|
|
3847
|
+
appEnv: clean(options.appEnvSecretName, `open-uptime/${stage}/app/env`),
|
|
3848
|
+
hostedToken: clean(options.hostedTokenSecretName, `open-uptime/${stage}/hosted-token`),
|
|
3849
|
+
publicProbe: clean(options.publicProbeSecretName, `open-uptime/${stage}/probe/public`),
|
|
3850
|
+
privateProbe: clean(options.privateProbeSecretName, `open-uptime/${stage}/probe/private`),
|
|
3851
|
+
reporting: clean(options.reportingSecretName, `open-uptime/${stage}/reporting`)
|
|
3821
3852
|
};
|
|
3822
3853
|
const services = [
|
|
3823
|
-
servicePlan(prefix, stage, "web",
|
|
3854
|
+
servicePlan(prefix, stage, "web", 1, image, workspaceId, secrets, {
|
|
3824
3855
|
HASNA_UPTIME_MODE: "hosted",
|
|
3856
|
+
HASNA_UPTIME_HOSTED_SQLITE_DB: hostedSqliteDbPath,
|
|
3825
3857
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
3826
3858
|
HASNA_UPTIME_HOSTNAME: hostname
|
|
3827
3859
|
}),
|
|
3828
|
-
servicePlan(prefix, stage, "scheduler",
|
|
3860
|
+
servicePlan(prefix, stage, "scheduler", 0, image, workspaceId, secrets, {
|
|
3829
3861
|
HASNA_UPTIME_MODE: "hosted",
|
|
3830
3862
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
3831
3863
|
HASNA_UPTIME_COMPONENT: "scheduler"
|
|
3832
3864
|
}),
|
|
3833
|
-
servicePlan(prefix, stage, "public-probe",
|
|
3865
|
+
servicePlan(prefix, stage, "public-probe", 0, image, workspaceId, secrets, {
|
|
3834
3866
|
HASNA_UPTIME_MODE: "hosted",
|
|
3835
3867
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
3836
3868
|
HASNA_UPTIME_COMPONENT: "public-probe",
|
|
3837
3869
|
HASNA_UPTIME_PROBE_LOCATION: region
|
|
3838
3870
|
}),
|
|
3839
|
-
servicePlan(prefix, stage, "reporter",
|
|
3871
|
+
servicePlan(prefix, stage, "reporter", 0, image, workspaceId, secrets, {
|
|
3840
3872
|
HASNA_UPTIME_MODE: "hosted",
|
|
3841
3873
|
HASNA_UPTIME_WORKSPACE_ID: workspaceId,
|
|
3842
3874
|
HASNA_UPTIME_COMPONENT: "reporter"
|
|
@@ -3849,7 +3881,7 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3849
3881
|
];
|
|
3850
3882
|
return {
|
|
3851
3883
|
kind: "open-uptime.aws-deployment-plan",
|
|
3852
|
-
version:
|
|
3884
|
+
version: 2,
|
|
3853
3885
|
generatedAt: new Date().toISOString(),
|
|
3854
3886
|
status: "blocked",
|
|
3855
3887
|
canApply: false,
|
|
@@ -3862,10 +3894,13 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3862
3894
|
mode: "hosted",
|
|
3863
3895
|
resources: {
|
|
3864
3896
|
ecrRepository,
|
|
3897
|
+
imageBuilder: `${prefix}-${stage}-image-builder`,
|
|
3865
3898
|
ecsCluster: cluster,
|
|
3866
3899
|
services,
|
|
3867
3900
|
vpcId: clean(options.vpcId, DEFAULT_VPC_ID),
|
|
3868
|
-
|
|
3901
|
+
efsFileSystem: `${prefix}-${stage}-data`,
|
|
3902
|
+
efsAccessPoint: `${prefix}-${stage}-uptime`,
|
|
3903
|
+
hostedSqliteDbPath,
|
|
3869
3904
|
evidenceBucket,
|
|
3870
3905
|
loadBalancer: `${prefix}-${stage}-alb`,
|
|
3871
3906
|
targetGroups: [`${prefix}-${stage}-web-tg`],
|
|
@@ -3875,7 +3910,8 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3875
3910
|
`${prefix}-${stage}-scheduler-sg`,
|
|
3876
3911
|
`${prefix}-${stage}-public-probe-sg`,
|
|
3877
3912
|
`${prefix}-${stage}-reporter-sg`,
|
|
3878
|
-
`${prefix}-${stage}-migration-sg
|
|
3913
|
+
`${prefix}-${stage}-migration-sg`,
|
|
3914
|
+
`${prefix}-${stage}-efs-sg`
|
|
3879
3915
|
],
|
|
3880
3916
|
secrets,
|
|
3881
3917
|
logGroups: services.map((service) => service.logGroup),
|
|
@@ -3887,10 +3923,10 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3887
3923
|
image: {
|
|
3888
3924
|
repository: ecrRepository,
|
|
3889
3925
|
uri: image,
|
|
3890
|
-
dockerfile: "Dockerfile",
|
|
3891
|
-
buildCommand: `
|
|
3926
|
+
dockerfile: "Dockerfile.package",
|
|
3927
|
+
buildCommand: `BLOCKED: after infra approval, AWS CodeBuild builds Dockerfile.package from @hasna/uptime@${runtimePackageVersion} into ${imageRepositoryUri}`,
|
|
3892
3928
|
pushCommands: [
|
|
3893
|
-
|
|
3929
|
+
`BLOCKED: start ${prefix}-${stage}-image-builder only through the approved deploy pipeline after @hasna/uptime@${runtimePackageVersion} is published`,
|
|
3894
3930
|
"BLOCKED: deploy services by immutable image digest, not by mutable tags"
|
|
3895
3931
|
]
|
|
3896
3932
|
},
|
|
@@ -3905,19 +3941,22 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3905
3941
|
runbook: {
|
|
3906
3942
|
preflight: [
|
|
3907
3943
|
`aws sts get-caller-identity --profile ${accountName}`,
|
|
3908
|
-
`aws rds describe-db-instances --db-instance-identifier ${clean(options.rdsInstanceId, DEFAULT_RDS)} --region ${region}`,
|
|
3909
3944
|
`aws ec2 describe-vpcs --vpc-ids ${clean(options.vpcId, DEFAULT_VPC_ID)} --region ${region}`,
|
|
3945
|
+
`aws efs describe-file-systems --region ${region}`,
|
|
3910
3946
|
"Confirm the infra repository and Terraform/CloudFormation owner before live mutation."
|
|
3911
3947
|
],
|
|
3912
3948
|
provision: [
|
|
3913
3949
|
`Infra PR must declare or update ECR repository ${ecrRepository}.`,
|
|
3950
|
+
`Infra PR must declare CodeBuild image builder ${prefix}-${stage}-image-builder for @hasna/uptime@${runtimePackageVersion}.`,
|
|
3914
3951
|
`Infra PR must declare hardened S3 evidence bucket ${evidenceBucket} with KMS, versioning, lifecycle, and public access block.`,
|
|
3952
|
+
`Infra PR must declare encrypted EFS ${prefix}-${stage}-data with access point, mount targets, and AWS Backup plan.`,
|
|
3915
3953
|
`Infra PR must declare ECS/Fargate cluster ${cluster}, ALB, target groups, security groups, IAM roles, CloudWatch log groups, and Secrets Manager refs.`,
|
|
3916
3954
|
"Only apply the infra plan from the approved infrastructure repository after review evidence is attached."
|
|
3917
3955
|
],
|
|
3918
3956
|
deploy: [
|
|
3919
3957
|
"Build and publish the image only after the Dockerfile/container target is reviewed.",
|
|
3920
|
-
|
|
3958
|
+
`Start the AWS image builder for @hasna/uptime@${runtimePackageVersion} and record the pushed image digest.`,
|
|
3959
|
+
"For the EFS SQLite bridge, do not run migration, scheduler, public-probe, or reporter tasks; keep them at desired count 0 until Postgres and cloud leases exist.",
|
|
3921
3960
|
`Register task definitions for ${services.map((service) => service.name).join(", ")} using valueFrom secrets.`,
|
|
3922
3961
|
`Update ECS services in cluster ${cluster} one component at a time through the approved deploy pipeline.`,
|
|
3923
3962
|
`Create Route53/edge record for ${hostname} only after ALB health checks pass and auth denial smokes succeed.`
|
|
@@ -3926,7 +3965,7 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3926
3965
|
"Keep previous task definition ARNs before each service update.",
|
|
3927
3966
|
"Rollback through the approved deploy pipeline to the previously recorded task definition ARNs.",
|
|
3928
3967
|
"Disable scheduler/reporter services before data rollback.",
|
|
3929
|
-
"Restore
|
|
3968
|
+
"Restore EFS backup recovery point only after explicit operator approval and audit record."
|
|
3930
3969
|
],
|
|
3931
3970
|
spark01: [
|
|
3932
3971
|
"Create a private probe identity with a caller-managed public key.",
|
|
@@ -3935,18 +3974,19 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3935
3974
|
]
|
|
3936
3975
|
},
|
|
3937
3976
|
blockers: [
|
|
3938
|
-
"The
|
|
3939
|
-
"
|
|
3977
|
+
"The infrastructure owner repository was not found in this workspace.",
|
|
3978
|
+
"The EFS SQLite bridge is single-writer only: web target desired count is 1 and scheduler/public-probe/reporter targets remain 0 until Postgres and cloud leases exist.",
|
|
3940
3979
|
"Hosted production auth/RBAC must replace broad static hosted-token operation before exposure.",
|
|
3941
3980
|
"Public probe execution still needs DNS, redirect, and rebinding SSRF enforcement plus cloud check-job leases.",
|
|
3942
3981
|
"Spark01 hosted probe enrollment, claim, submit, heartbeat, revocation, and rotation are not cloud-backed yet."
|
|
3943
3982
|
],
|
|
3944
3983
|
requiredEvidence: [
|
|
3945
3984
|
"Infrastructure PR/synth/plan from the approved infra repository.",
|
|
3946
|
-
"
|
|
3985
|
+
"CodeBuild image-builder run, container smoke, and immutable image digest.",
|
|
3947
3986
|
"ECS task definitions using secrets.valueFrom only.",
|
|
3948
3987
|
"ALB/TLS/DNS/auth denial smokes and web alarm checks.",
|
|
3949
|
-
"
|
|
3988
|
+
"Single-writer ECS evidence: one web task maximum and no scheduler/public-probe/reporter EFS mounts.",
|
|
3989
|
+
"EFS encryption, access point, mount-target, AWS Backup, and restore-drill evidence.",
|
|
3950
3990
|
"S3 bucket KMS, versioning, lifecycle, and public-access-block evidence.",
|
|
3951
3991
|
"Spark01 private-probe registration, key-file mode, heartbeat, and revocation evidence."
|
|
3952
3992
|
],
|
|
@@ -3956,7 +3996,9 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
3956
3996
|
hostedLocalSqliteAllowed: false,
|
|
3957
3997
|
notes: [
|
|
3958
3998
|
"This plan generator does not call AWS.",
|
|
3959
|
-
"
|
|
3999
|
+
"Blocked plan output intentionally avoids copy-pastable AWS mutation commands.",
|
|
4000
|
+
"Hosted runtime uses explicit EFS-backed SQLite at HASNA_UPTIME_HOSTED_SQLITE_DB until the async Postgres adapter exists.",
|
|
4001
|
+
"Do not set HASNA_UPTIME_DATABASE_URL for hosted tasks until the Postgres adapter is implemented.",
|
|
3960
4002
|
"Secrets are represented as secret names/refs and must be injected with valueFrom.",
|
|
3961
4003
|
"Actual deploy belongs in the deploy_release_operate_final goal node after infra review."
|
|
3962
4004
|
]
|
|
@@ -4048,7 +4090,7 @@ function servicePlan(prefix, stage, role, desiredCount, image, workspaceId, secr
|
|
|
4048
4090
|
HASNA_UPTIME_IMAGE: image,
|
|
4049
4091
|
...environment
|
|
4050
4092
|
},
|
|
4051
|
-
secrets: role === "web" ? {
|
|
4093
|
+
secrets: role === "web" ? { APP_ENV: secrets.appEnv, HASNA_UPTIME_HOSTED_TOKEN: secrets.hostedToken } : role === "public-probe" ? { PROBE_CONFIG: secrets.publicProbe } : role === "reporter" ? { REPORTING_CONFIG: secrets.reporting } : { APP_ENV: secrets.appEnv }
|
|
4052
4094
|
};
|
|
4053
4095
|
}
|
|
4054
4096
|
function clean(value, fallback) {
|
package/dist/mcp/index.js
CHANGED
|
@@ -15097,7 +15097,7 @@ function stableJson(value) {
|
|
|
15097
15097
|
}
|
|
15098
15098
|
|
|
15099
15099
|
// src/store.ts
|
|
15100
|
-
import { copyFileSync, existsSync, mkdirSync, statSync } from "fs";
|
|
15100
|
+
import { copyFileSync, existsSync, mkdirSync, statfsSync, statSync } from "fs";
|
|
15101
15101
|
import { dirname, join as join2 } from "path";
|
|
15102
15102
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
15103
15103
|
import { Database } from "bun:sqlite";
|
|
@@ -15116,6 +15116,8 @@ function uptimeHostedFallbackDbPath() {
|
|
|
15116
15116
|
}
|
|
15117
15117
|
|
|
15118
15118
|
// src/store.ts
|
|
15119
|
+
var DEFAULT_HOSTED_SQLITE_DB_PATH = "/data/uptime/uptime.db";
|
|
15120
|
+
var NFS_SUPER_MAGIC = 26985;
|
|
15119
15121
|
var SECRET_URL_PARAM_PATTERN = /(token|secret|password|passwd|api[_-]?key|access[_-]?token|auth|credential|session)/i;
|
|
15120
15122
|
var REQUIRED_TABLES = [
|
|
15121
15123
|
"schema_migrations",
|
|
@@ -15152,18 +15154,39 @@ class UptimeStore {
|
|
|
15152
15154
|
this.mode = resolveRuntimeMode(options.mode ?? "local");
|
|
15153
15155
|
const cloudDatabaseUrl = options.cloudDatabaseUrl ?? process.env.HASNA_UPTIME_DATABASE_URL;
|
|
15154
15156
|
if (this.mode === "hosted" && cloudDatabaseUrl) {
|
|
15155
|
-
throw new Error("hosted
|
|
15157
|
+
throw new Error("hosted Postgres adapter is not implemented yet; use HASNA_UPTIME_HOSTED_SQLITE_DB on cloud-mounted storage for the current hosted deployment path");
|
|
15156
15158
|
}
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
+
const hostedSqliteDbPath = options.hostedSqliteDbPath ?? process.env.HASNA_UPTIME_HOSTED_SQLITE_DB;
|
|
15160
|
+
if (this.mode === "hosted" && hostedSqliteDbPath) {
|
|
15161
|
+
if (hostedSqliteDbPath === ":memory:" || !hostedSqliteDbPath.startsWith("/")) {
|
|
15162
|
+
throw new Error("HASNA_UPTIME_HOSTED_SQLITE_DB must be an absolute path on mounted cloud storage");
|
|
15163
|
+
}
|
|
15164
|
+
const approvedHostedPath = hostedSqliteDbPath === DEFAULT_HOSTED_SQLITE_DB_PATH;
|
|
15165
|
+
if (!approvedHostedPath && !allowHostedLocalStore(options.allowHostedLocalStore)) {
|
|
15166
|
+
throw new Error(`HASNA_UPTIME_HOSTED_SQLITE_DB must be ${DEFAULT_HOSTED_SQLITE_DB_PATH}; set HASNA_UPTIME_ALLOW_HOSTED_LOCAL_STORE=1 only for explicit local fallback testing`);
|
|
15167
|
+
}
|
|
15168
|
+
const verifiedCloudMount = approvedHostedPath && isNfsMount(dirname(hostedSqliteDbPath));
|
|
15169
|
+
if (approvedHostedPath && !verifiedCloudMount && !allowHostedLocalStore(options.allowHostedLocalStore)) {
|
|
15170
|
+
throw new Error(`${DEFAULT_HOSTED_SQLITE_DB_PATH} must be on a mounted EFS/NFS filesystem; refusing to create hosted task-local SQLite`);
|
|
15171
|
+
}
|
|
15172
|
+
this.dataMode = verifiedCloudMount ? "hosted-efs-sqlite" : "hosted-local-sqlite";
|
|
15173
|
+
this.dbPath = hostedSqliteDbPath;
|
|
15174
|
+
} else if (this.mode === "hosted") {
|
|
15175
|
+
if (!allowHostedLocalStore(options.allowHostedLocalStore)) {
|
|
15176
|
+
throw new Error("hosted mode requires HASNA_UPTIME_HOSTED_SQLITE_DB on mounted cloud storage; set HASNA_UPTIME_ALLOW_HOSTED_LOCAL_STORE=1 only for explicit local fallback testing");
|
|
15177
|
+
}
|
|
15178
|
+
this.dataMode = "hosted-local-sqlite";
|
|
15179
|
+
this.dbPath = options.dbPath ?? uptimeHostedFallbackDbPath();
|
|
15180
|
+
} else {
|
|
15181
|
+
this.dataMode = "local-sqlite";
|
|
15182
|
+
this.dbPath = options.dbPath ?? uptimeDbPath();
|
|
15159
15183
|
}
|
|
15160
|
-
|
|
15161
|
-
this.dbPath = options.dbPath ?? (this.mode === "hosted" ? uptimeHostedFallbackDbPath() : uptimeDbPath());
|
|
15162
|
-
if (this.dbPath !== ":memory:") {
|
|
15184
|
+
if (this.dbPath !== ":memory:" && this.dataMode !== "hosted-efs-sqlite") {
|
|
15163
15185
|
mkdirSync(dirname(this.dbPath), { recursive: true });
|
|
15164
15186
|
}
|
|
15165
15187
|
this.db = new Database(this.dbPath, { create: true });
|
|
15166
|
-
this.db.run("PRAGMA journal_mode = WAL");
|
|
15188
|
+
this.db.run(this.dataMode === "hosted-efs-sqlite" ? "PRAGMA journal_mode = DELETE" : "PRAGMA journal_mode = WAL");
|
|
15189
|
+
this.db.run("PRAGMA busy_timeout = 5000");
|
|
15167
15190
|
this.db.run("PRAGMA foreign_keys = ON");
|
|
15168
15191
|
this.migrate();
|
|
15169
15192
|
}
|
|
@@ -16043,6 +16066,13 @@ function resolveRuntimeMode(mode) {
|
|
|
16043
16066
|
function allowHostedLocalStore(value) {
|
|
16044
16067
|
return value === true || process.env.HASNA_UPTIME_ALLOW_HOSTED_LOCAL_STORE === "1";
|
|
16045
16068
|
}
|
|
16069
|
+
function isNfsMount(path) {
|
|
16070
|
+
try {
|
|
16071
|
+
return statfsSync(path).type === NFS_SUPER_MAGIC;
|
|
16072
|
+
} catch {
|
|
16073
|
+
return false;
|
|
16074
|
+
}
|
|
16075
|
+
}
|
|
16046
16076
|
function verifyBackupFile(backupPath) {
|
|
16047
16077
|
const db = new Database(backupPath, { readonly: true });
|
|
16048
16078
|
try {
|
package/dist/service.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export interface UptimeServiceOptions extends UptimeStoreOptions {
|
|
|
9
9
|
export interface UptimeStoreLike {
|
|
10
10
|
readonly dbPath: string;
|
|
11
11
|
readonly mode: "local" | "hosted";
|
|
12
|
-
readonly dataMode: "local-sqlite" | "hosted-local-sqlite";
|
|
12
|
+
readonly dataMode: "local-sqlite" | "hosted-local-sqlite" | "hosted-efs-sqlite";
|
|
13
13
|
close(): void;
|
|
14
14
|
createMonitor(input: ImportedMonitorInput, options?: {
|
|
15
15
|
allowBrowserPage?: boolean;
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,EAA8C,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAErK,OAAO,EAAsC,KAAK,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,KAAK,4BAA4B,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClP,OAAO,EAAuC,KAAK,wBAAwB,EAAE,KAAK,uBAAuB,EAAE,KAAK,YAAY,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC7K,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,SAAS,EACT,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,yBAAyB,EACzB,aAAa,EACd,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|